2016-09-15 121 views
0

我有兩個數據幀df_a,df_b如何檢索多個匹配元素?

set.seed(143) 
df_a <- data.frame(colA = sample(1:10, 10, replace=T), colB = sample(LETTERS[1:20],10)) 
df_a 
# colA colB 
#1 10 I 
#2  1 D 
#3  8 R 
#4  5 F 
#5  1 N 
#6 10 P 
#7  7 E 
#8  6 S 
#9  6 T 
#10 4 C 

df_b <- data.frame(colA = sample(1:10, 10, replace=T)) 
df_b 
# colA 
#1  9 
#2  3 
#3  9 
#4  9 
#5  3 
#6 10 
#7 10 
#8  7 
#9  4 
#10 7 

我必須基於在這兩個數據幀的colA的匹配數據幀從df_acolB更新colB與值。

df_a[match(df_b$colA, df_a$colA),'colB'] 
# [1] <NA> <NA> <NA> <NA> <NA> I I E C E 
#Levels: C D E F I N P R S T 

輸出不會給出超過一個匹配元素(不是一個驚喜!)。例如,10有兩個值I,P但只給出I

Expected Output(something like this, maybe?): 

df_a[match(df_b$colA, df_a$colA),'colB'] 
# [1] <NA> <NA> <NA> <NA> <NA> I,P I,P E C E 
#Levels: C D E F I N P R S T 

由於match()函數只返回第一個匹配的值,有沒有像which()%in%任何其他替代實現的任務嗎?

+1

我會用'合併(DF_B,DF_A,通過= 「可樂」,all.x = TRUE)',但做什麼用'可樂== 10'? –

+0

@ m-dz需要檢索所有可能的匹配 – Prradep

+0

因此,我的評論中的代碼是否符合您的期望? –

回答

2

您需要aggregatepaste相同的比賽一起,然後合併,即

merge(df_b, aggregate(colB ~ colA, df_a, paste, collapse = ','), by = 'colA', all.x = TRUE) 
# colA colB 
#1  3 <NA> 
#2  3 <NA> 
#3  4 C 
#4  7 E 
#5  7 E 
#6  9 <NA> 
#7  9 <NA> 
#8  9 <NA> 
#9 10 I,P 
#10 10 I,P 
2

如果你想擁有df_b按照原來的順序,我會用data.table如下:

library(data.table) 
setDT(df_b) 
setDT(df_a) 

df_a[, sapply(.SD, paste, collapse = ","), by = "colA"][df_b, , on = "colA"] 

首先,df_a[, sapply(.SD, paste, collapse = ",") , by = "colA"]與@Sotos建議的df_a完全相同,然後[df_b, , on = "colA"]將其結果與合併。

結果是:

colA V1 
1: 9 NA 
2: 3 NA 
3: 9 NA 
4: 9 NA 
5: 3 NA 
6: 10 I,P 
7: 10 I,P 
8: 7 E 
9: 4 C 
10: 7 E