R - Сопоставить значения, используя несколько идентификаторов (когда порядок поиска идентификаторов является случайным) - PullRequest
0 голосов
/ 28 июня 2018

Мой вопрос является продолжением этого вопроса . Здесь я открываю новый вопрос - поскольку он сильно отличается от предыдущего.

Предположим, у меня есть следующие два набора данных:

df1 = data.frame(PersonId1=c(1,2,3,4,5,6,7,8,9,10,1),PersonId2=c(11,12,13,14,15,16,17,18,19,20,11),
         Played_together = c(1,0,0,1,1,0,0,0,1,0,1),
         Event=c(1,1,1,1,2,2,2,2,2,2,2),
         Utility=c(20,-2,-5,10,30,2,1,.5,50,-1,60))

Это выглядит так:

   PersonId1 PersonId2 Played_together Event Utility
1          1        11               1     1    20.0
2          2        12               0     1    -2.0
3          3        13               0     1    -5.0
4          4        14               1     1    10.0
5          5        15               1     2    30.0
6          6        16               0     2     2.0
7          7        17               0     2     1.0
8          8        18               0     2     0.5
9          9        19               1     2    50.0
10        10        20               0     2    -1.0
11         1        11               1     2    60.0

.

df2 = data.frame(PersonId1=c(11,15,9,1),PersonId2=c(1,5,19,11),
         Played_together = c(1,1,1,1),
         Event=c(1,2,2,2),Utility=c(25,36,51,64))

Это выглядит так:

PersonId1 PersonId2 Played_together Event Utility
1        11         1               1     1      25
2        15         5               1     2      36
3         9        19               1     2      51
4         1        11               1     2      64

Я хотел бы сделать следующее: Посмотрите каждую пару ( в каждом событии и по сыгранному == 1 ) в df2 и сопоставьте ее с наблюдениями в df1 . Если это совпадение, создайте новый столбец в df1, который называется «Утилита из df2». Это не так, поставьте 0.

Проблема для меня заключается в том, что порядок лиц не одинаков для df1 и df2. Например, в строке 1 df1 для события == 1 и играл_в целом == 1 мы видим: personid1 = 1 и personid2 = 11, тогда как в df2 в строке 1 у меня есть personid1 = 11 и personid2 = 1, для события == 1 и played_together == 1. Таким образом, два одинаковы. Я хотел бы взять значение утилиты из df2 и поместить его в новый столбец в df1. если совпадения нет, то ставьте 0.

Окончательный кадр данных должен выглядеть следующим образом:

    PersonId1 PersonId2 Played_together Event Utility Utility_from_df2
1          1        11               1     1    20.0               25
2          2        12               0     1    -2.0                0
3          3        13               0     1    -5.0                0
4          4        14               1     1    10.0                0
5          5        15               1     2    30.0               36
6          6        16               0     2     2.0                0
7          7        17               0     2     1.0                0
8          8        18               0     2     0.5                0
9          9        19               1     2    50.0               51
10        10        20               0     2    -1.0                0
11         1        11               1     2    60.0               64

Заранее большое спасибо.

1 Ответ

0 голосов
/ 28 июня 2018

Использование dplyr и data.table:

df2 = data.frame(PersonId1=c(11,15,9,1),PersonId2=c(1,5,19,11),
                 Played_together = c(1,1,1,1),
                 Event=c(1,2,2,2),
                 Utility=c(25,36,51,64)) # you had missed adding Utility in your ques


library(data.table)
library(dplyr)
df3 <- copy(df2)
colnames(df2) <- c("PersonId2", "PersonId1", "Played_together", "Event", "Utility")
setDT(df2)
df2 <- df2[, c("PersonId2", "PersonId1", "Utility", "Event")]
df3 <- df3[, c("PersonId2", "PersonId1", "Utility", "Event")]
df <- left_join(df1, df2, c("PersonId2", "PersonId1", "Event"))
df <- left_join(df, df3, by = c("PersonId2", "PersonId1", "Event"))
setDT(df)
df[, Utility_from_df2 := ifelse(is.na(Utility), Utility.y, ifelse(is.na(Utility.y), Utility, 0))]
df[is.na(df)] <- 0
df[, c("Utility.y", "Utility") := NULL]
setnames(df, "Utility.x", "Utility")

Желаемый вывод:

     PersonId1 PersonId2 Played_together Event Utility Utility_from_df2
 1:         1        11               1     1    20.0               25
 2:         2        12               0     1    -2.0                0
 3:         3        13               0     1    -5.0                0
 4:         4        14               1     1    10.0                0
 5:         5        15               1     2    30.0               36
 6:         6        16               0     2     2.0                0
 7:         7        17               0     2     1.0                0
 8:         8        18               0     2     0.5                0
 9:         9        19               1     2    50.0               51
10:        10        20               0     2    -1.0                0
11:         1        11               1     2    60.0               64
...