2016-09-15 102 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