以下问题:我有两个数据帧,我希望将数据帧data1中的一个向量与数据帧data2中的向量进行匹配。
data1 <- data.frame(v1 = c("horse", "duck", "bird"), v2 = c(1,2,3))
data2 <- data.frame(v1 = c("car, horse, mouse", "duck, bird", "bird"))
如果data2中的字符串匹配,则应将其替换为data1中对应的值v2。结果如下所示:
for(i in 1:nrow(data1)) data2[,1] <- gsub(data1[i,1], data1[i,2], data2[,1], fixed=T)
data2
但是,有没有想法使用矢量化解决方案而不是for循环来创建更好的数据集?
提前致谢!
- 更新:
当我遇到这种情况时会发生什么情况,两个数据帧的长度不一样?
data2 <- data.frame(v1 = c("car, horse, mouse", "duck, bird","bird", "bird"))
当我使用此解决方案时:
data2$v1 <- mapply(sub, data1$v1, data1$v2, data2$v1)
然后我收到以下警告信息:
1:在mapply中(sub,data1 $ v1,data1 $ v2,data2 $ v1):更长的参数 不是长度为2的倍数:在mapply中(sub,data1 $ v1, data1 $ v2,data2 $ v1):较长的参数不是长度的倍数 较短的
但是,mgsub解决方案非常完美!谢谢!
答案 0 :(得分:5)
“stringi”包中的大多数参数都接受矢量化输入,因此您应该能够使用srti_replace_all
,如下所示:
library(stringi)
stri_replace_all_fixed(data2$v1, data1$v1, data1$v2)
# [1] "car, 1, mouse" "2, bird" "3"
获取data.frame
:
data.frame(v1 = stri_replace_all_fixed(data2$v1, data1$v1, data1$v2))
# v1
# 1 car, 1, mouse
# 2 2, bird
# 3 3
答案 1 :(得分:5)
使用更新的data2
。 nrows
和data1
之间的data2
不同,在此,我们假设两个数据集的v1
列之间的任何匹配都应替换为{{1}的相应值} v2
中的列。
data1
注意 library(qdap)
mgsub(as.character(data1$v1), data1$v2, data2$v1)
#[1] "car, 1, mouse" "2, 3" "3" "3"
有一些错误处理,可以处理在较大字符串中找到子字符串并且两者都位于“要替换”的情况名单。以下是mgsub
和horse
的示例:
horses
data1 <- data.frame(v1 = c("horse", "duck", "bird", "horse", "horses"), v2 = 1:5)
data2 <- data.frame(v1 = c("car, horses, mouse", "duck, bird, horse", "bird"))
library(stringi)
stri_replace_all_fixed(data2$v1, data1$v1, data1$v2)
## [1] "car, 1s, mouse" "2, bird, horse" "3" "car, 4s, mouse" "duck, bird, horse"
## Warning message:
## In stri_replace_all_fixed(data2$v1, data1$v1, data1$v2) :
## longer object length is not a multiple of shorter object length
library(qdap)
mgsub(as.character(data1$v1), data1$v2, data2$v1)
## [1] "car, 5, mouse" "2, 3, 4" "3"
确保首先替换较长的单词。这使mgsub
更慢但更安全。根据您的数据类型/需求,这里的解决方案可能有用。