Объединение и сопоставление двух фреймов данных в R

#r #join #match #dplyr

#r #Присоединиться #сопоставление #dplyr

Вопрос:

У меня есть два фрейма данных. Первый фрейм данных состоит из: четырех столбцов 1) Идентификатор, 2) Сайт, 3) Глубина и 3) Плотность. Второй фрейм данных состоит из 3 столбцов: 1) идентификатор, 2) Сайт и 3) Выбор (т. е. Любимый сайт).

df1

   ID  Site Depth Density      
  1     B   0.1       0
  2     C   0.2       0
  3     C   0.2       1
  4     A  0.05       0
  5     A  0.05       1
  6     B   0.1       1
  7     B   0.1       2
  8     B   0.1       3
  9     D   0.3       0
 10     C   0.2       2
 11     D   0.3       1
 12     D   0.3       2
 13     D   0.3       3
 14     D   0.3       4
 15     D   0.3       5
 

df 2

      ID     Site   Choices
      1       A     No
      1       B     Yes
      1       C     No
      1       D     No
      2       A     No
      2       B     No
      2       C     Yes
      2       D     No
      3       A     No
      3       B     No
      3       C     Yes
      3       D     No
      4       A     Yes
      4       B     No
      4       C     No
      4       D     No
 

Я пытаюсь добавить столбец в df2, в котором указаны плотности каждого идентификатора на каждом сайте, когда идентификатор выбрал свой любимый сайт.

Желаемый результат:

      ID     Site   Depth  Density    Choice
      1       A      0.05     0         No
      1       B      0.1      0         Yes
      1       C      0.2      0         No
      1       D      0.3      0         No
      2       A      0.05     0         No
      2       B      0.1      1         No
      2       C      0.2      0         Yes
      2       D      0.3      0         No
      3       A      0.05     0         No
      3       B      0.1      0         No
      3       C      0.2      1         Yes
      3       D      0.3      0         No
      4       A      0.05     0         Yes
      4       B      0.1      1         No
      4       C      0.2      2         No
      4       D      0.3      0         No
 

объяснение df2: когда ID 1 выбирал сайт B, плотность на сайтах A, B, C и D. была равна 0. Когда ID 2 выбирал C, плотность на сайте A составляла 0, на сайте B 1, на сайте C 0 и на сайте D 0. Когда ID 3 выбрал сайт C, плотность в A по-прежнему была равна 0 (ни один ID еще не выбрал сайт A), B имеет 1, C имеет 1, а сайт D 0, и так далее.

Я пытался использовать функцию полного объединения и функцию изменения, но я не получаю желаемого результата:

            df3<-df2 %>%
           full_join(df1, by = c("ID", "Site")) %>%
           group_by(ID) %>%
           mutate(Density= Density[Choice == "Yes"] ) %>%
           distinct(ID, Site, .keep_all = TRUE)
 

Комментарии:

1. Я думаю, у вас есть опечатка — ваш желаемый выходной идентификатор 3 сайта B показывает плотность 0 , но в вашем тексте говорится: «Когда ID 3 выбрал сайт C, плотность в … B имеет 1» . Я думаю, что ваш текст правильный, а желаемый результат неверный, но я хочу проверить, чтобы убедиться, что я понимаю.

Ответ №1:

Я думаю Density , что это общее количество групп, выбранных для каждого сайта. Чтобы вычислить это, я бы сделал это:

 df3 <- df2 %>%
  full_join(df1, by = c("ID", "Site")) %>%
  arrange(ID, site) %>%  ## make sure IDs are in ascending order
  group_by(Site) %>%
  mutate(Density = cumsum(Choice == "Yes"))
 

Комментарии:

1. Мне не повезло с размещением идентификаторов в порядке возрастания. Я использовал как функцию сортировки, так и «desc».

2. arrange(ID, site) помещает идентификаторы в порядке возрастания. В моем комментарии указывается цель этой строки кода, а не задание. Вам не нужно ничего добавлять, использовать sort и особенно не desc использовать для конечного порядка desc — противоположного тому, что вы хотите.

3. Спасибо! В какой-то момент у меня все еще была проблема, но я исправил ее, упорядочив идентификаторы во фрейме данных, прежде чем пропустить его через симуляцию full_join.

4. @ Gregor Thomas быстрый вопрос: есть ли способ вернуться на одну временную метку в моделировании? Кажется, я ошибаюсь при сопоставлении плотностей?

5. Попробуйте Density = pmax(0, cumsum(Choice == "Yes") - 1)