Как объединить два кадра данных на общих столбцах в R с суммой других?
R Версия 2.11.1 32-бит в Windows 7
У меня есть два набора данных: data_A и data_B:
data_A
USER_A USER_B ACTION
1 11 0.3
1 13 0.25
1 16 0.63
1 17 0.26
2 11 0.14
2 14 0.28
Данные
USER_A USER_B ACTION
1 13 0.17
1 14 0.27
2 11 0.25
Теперь я хочу добавить ACTION data_B в data_A, если их USER_A и USER_B равны. В качестве примера выше результат будет выглядеть следующим образом:
data_A
USER_A USER_B ACTION
1 11 0.3
1 13 0.25+0.17
1 16 0.63
1 17 0.26
2 11 0.14+0.25
2 14 0.28
Итак, как я мог его достичь?
Ответы
Ответ 1
Вы можете использовать ddply
в пакете plyr
и объединить его с merge
:
library(plyr)
ddply(merge(data_A, data_B, all.x=TRUE),
.(USER_A, USER_B), summarise, ACTION=sum(ACTION))
Обратите внимание, что merge
вызывается с параметром all.x=TRUE
- это возвращает все значения в первом data.frame, переданном в merge
, то есть data_A:
USER_A USER_B ACTION
1 1 11 0.30
2 1 13 0.25
3 1 16 0.63
4 1 17 0.26
5 2 11 0.14
6 2 14 0.28
Ответ 2
Подобная вещь довольно проста в использовании операции с базами данных. Здесь я использую пакет sqldf
, чтобы сделать левое (внешнее) соединение, а затем суммировать результирующий объект:
require(sqldf)
tmp <- sqldf("select * from data_A left join data_B using (USER_A, USER_B)")
Это приводит к:
> tmp
USER_A USER_B ACTION ACTION
1 1 11 0.30 NA
2 1 13 0.25 0.17
3 1 16 0.63 NA
4 1 17 0.26 NA
5 2 11 0.14 0.25
6 2 14 0.28 NA
Теперь нам просто нужно собрать два столбца ACTION
:
data_C <- transform(data_A, ACTION = rowSums(tmp[, 3:4], na.rm = TRUE))
Что дает желаемый результат:
> data_C
USER_A USER_B ACTION
1 1 11 0.30
2 1 13 0.42
3 1 16 0.63
4 1 17 0.26
5 2 11 0.39
6 2 14 0.28
Это можно сделать с помощью стандартной функции R merge
:
> merge(data_A, data_B, by = c("USER_A","USER_B"), all.x = TRUE)
USER_A USER_B ACTION.x ACTION.y
1 1 11 0.30 NA
2 1 13 0.25 0.17
3 1 16 0.63 NA
4 1 17 0.26 NA
5 2 11 0.14 0.25
6 2 14 0.28 NA
Итак, мы можем заменить вызов sqldf()
выше:
tmp <- merge(data_A, data_B, by = c("USER_A","USER_B"), all.x = TRUE)
в то время как вторая строка с использованием transform()
остается неизменной.