我有两个看起来像这些的data.frame:
>df1
V1
a
b
c
d
e
>df2
V1 V2
1 a,k,l
2 c,m,n
3 z,b,s
4 l,m,e
5 t,r,d
我想将df1$V1
中的值与来自df2$V2
的值相匹配,并将新列添加到df1
,该列对应于df2$V1
的匹配和值,欲望输出将是:
>df1
V1 V2
a 1
b 3
c 2
d 5
e 4
我尝试过这种方法,但只有在df2$V2
只包含一个元素时才有效:
match(as.character(df1[,1]), strsplit(as.character(df2[,2], ",")) -> idx
df1$V2 <- df2[idx,1]
非常感谢
答案 0 :(得分:1)
您可以使用grep
,它将返回找到的字符串的位置:
sapply(df1$V1, grep, x = df2$V2)
# a b c d e
# 1 3 2 5 4
如果您希望重复,可以使用paste
。
让我们修改您的数据,以便重复:
df2$V2[3] <- "z,b,s,a"
并相应地修改解决方案:
sapply(df1$V1, function(z) paste(grep(z, x = df2$V2), collapse = ";"))
# a b c d e
# "1;3" "3" "2" "5" "4"
答案 1 :(得分:1)
这是一种方法:
library(qdap)
key <- setNames(strsplit(as.character(df2$V2), ","), df2$V1)
df1$V2 <- as.numeric(df1$V1 %l% key)
df1
## V1 V2
## 1 a 1
## 2 b 3
## 3 c 2
## 4 d 5
## 5 e 4
首先,我们使用strsplit
创建了一个命名列表。然后我们使用qdap的lookup
运算符%l%
来匹配值并创建一个新列(我转换为数字虽然这可能不是必需的)。
答案 2 :(得分:1)
与Tyler的答案类似,但在使用stack
:
df.stack <- stack(setNames(strsplit(as.character(df2$V2), ","), df2$V1))
transform(df1, V2=df.stack$ind[match(V1, df.stack$values)])
产生
V1 V2
1 a 1
2 b 3
3 c 2
4 d 5
5 e 4
分割grep的一个好处是,使用grep,你冒着搜索a
和匹配alabama
等内容的风险(虽然你可以小心模式来缓解这种情况(即包括字边界等。)。
请注意,这只会找到第一个匹配值。