グーグルキーワードでは解決できなかったトリッキーなR問題を解決しようとしています。具体的には、値が別のデータフレームに表示されないデータフレームのサブセットを取得しようとしています。次に例を示します。
> test
number fruit ID1 ID2
item1 "number1" "apples" "22" "33"
item2 "number2" "oranges" "13" "33"
item3 "number3" "peaches" "44" "25"
item4 "number4" "apples" "12" "13"
> test2
number fruit ID1 ID2
item1 "number1" "papayas" "22" "33"
item2 "number2" "oranges" "13" "33"
item3 "number3" "peaches" "441" "25"
item4 "number4" "apples" "123" "13"
item5 "number3" "peaches" "44" "25"
item6 "number4" "apples" "12" "13"
item7 "number1" "apples" "22" "33"
Testとtest2の2つのデータフレームがあります。目標は、一部の値が同じであっても、test2の行全体を選択してtestに表示されないようにすることです。
必要な出力は次のようになります。
item1 "number1" "papayas" "22" "33"
item2 "number3" "peaches" "441" "25"
item3 "number4" "apples" "123" "13"
行または列の数は任意ですが、私の特定のケースでは、1つのデータフレームが他のデータフレームの直接のサブセットです。
私はRサブセット()、マージ()、およびwhich()関数を広範囲に使用しましたが、可能であれば、これらを組み合わせて使用して必要なものを取得する方法を理解できませんでした。
編集:これらの2つのテーブルを生成するために使用したRコードは次のとおりです。
test <- data.frame(c("number1", "apples", 22, 33), c("number2", "oranges", 13, 33),
c("number3", "peaches", 44, 25), c("number4", "apples", 12, 13))
test <- t(test)
rownames(test) = c("item1", "item2", "item3", "item4")
colnames(test) = c("number", "fruit", "ID1", "ID2")
test2 <- data.frame(data.frame(c("number1", "papayas", 22, 33), c("number2", "oranges", 13, 33),
c("number3", "peaches", 441, 25), c("number4", "apples", 123, 13),c("number3", "peaches", 44, 25), c("number4", "apples", 12, 13) ))
test2 <- t(test2)
rownames(test2) = c("item1", "item2", "item3", "item4", "item5", "item6")
colnames(test2) = c("number", "fruit", "ID1", "ID2")
前もって感謝します!
別の方法は次のとおりです。
x <- rbind(test2, test)
x[! duplicated(x, fromLast=TRUE) & seq(nrow(x)) <= nrow(test2), ]
# number fruit ID1 ID2
# item1 number1 papayas 22 33
# item3 number3 peaches 441 25
# item4 number4 apples 123 13
編集: 行名を保持するように変更されました。
これを解決するには、data.tableとsqldfを使用する2つの方法があります。
library(data.table)
test<- fread('
item number fruit ID1 ID2
item1 "number1" "apples" "22" "33"
item2 "number2" "oranges" "13" "33"
item3 "number3" "peaches" "44" "25"
item4 "number4" "apples" "12" "13"
')
test2<- fread('
item number fruit ID1 ID2
item1 "number1" "papayas" "22" "33"
item2 "number2" "oranges" "13" "33"
item3 "number3" "peaches" "441" "25"
item4 "number4" "apples" "123" "13"
item5 "number3" "peaches" "44" "25"
item6 "number4" "apples" "12" "13"
item7 "number1" "apples" "22" "33"
')
data.tableアプローチ。これにより、比較する列を選択できます。
setkey(test,item,number,fruit,ID1,ID2)
setkey(test2,item,number,fruit,ID1,ID2)
test[!test2]
item number fruit ID1 ID2
1: item1 number1 apples 22 33
2: item3 number3 peaches 44 25
3: item4 number4 apples 12 13
SQLアプローチ
sqldf('select * from test except select * from test2')
item number fruit ID1 ID2
1: item1 number1 apples 22 33
2: item3 number3 peaches 44 25
3: item4 number4 apples 12 13
Test2で新しい行ID列を作成し、データフレームをマージして、IDがマージ結果に含まれていない行を選択します。
test2 <- cbind(test2, id=seq_len(nrow(test2)))
matches <- merge(test1, test2)$id
test2 <- test2[-matches, ]
別のアプローチがありますが、それがどれだけうまくスケーリングするかはわかりません。
test2[!apply(test2, 1, paste, collapse = "") %in%
apply(test, 1, paste, collapse = ""), ]
# number fruit ID1 ID2
# item1 "number1" "papayas" "22" "33"
# item3 "number3" "peaches" "441" "25"
# item4 "number4" "apples" "123" "13"
これはnotすべての重複を削除します。たとえば、test2
重複がありました:
test2 <- rbind(test2, test2[1:3, ])
## Matthew's answer: Duplicates dropped
x <- rbind(test2, test)
x[! duplicated(x, fromLast=TRUE) & seq(nrow(x)) <= nrow(test2), ]
# number fruit ID1 ID2
# item4 "number4" "apples" "123" "13"
# item1 "number1" "papayas" "22" "33"
# item3 "number3" "peaches" "441" "25"
## This one: Duplicates retained
test2[!apply(test2, 1, paste, collapse = "") %in%
apply(test, 1, paste, collapse = ""), ]
# number fruit ID1 ID2
# item1 "number1" "papayas" "22" "33"
# item3 "number3" "peaches" "441" "25"
# item4 "number4" "apples" "123" "13"
# item1 "number1" "papayas" "22" "33"
# item3 "number3" "peaches" "441" "25"