Rバージョン2.11.1Windows7の32ビット
Data_Aとdata_Bの2つのデータセットを取得しました。
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
ここで、USER_AとUSER_Bが等しい場合、data_BのACTIONを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
では、どうすればそれを達成できますか?
パッケージ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
で呼び出されることに注意してください。これにより、merge
に渡された最初のdata.frameのすべての値が返されます。つまり、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
この種のことは、データベースのような操作で非常に簡単に行うことができます。ここでは、パッケージ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
_
ここで、2つの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()
を使用する2行目は同じままです。
私はパッケージを書きました safejoin これはこれを非常に簡潔に解決します:
# devtools::install_github("moodymudskipper/safejoin")
library(safejoin)
safe_left_join(data_A,data_B, by = c("USER_A", "USER_B"),
conflict = ~ .x+ ifelse(is.na(.y),0,.y))
# 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
競合する場合、conflict
引数に指定された関数は、競合する列のペアで使用されます