我正在处理R
中的一些文本,我想完成一项与将一个数据帧中的字符串与其他数据帧中保存的字符串进行比较相关的任务,以及在重合时在第一个数据帧中分配一个值。我的初始数据框是DF1
:
DF1 <- data.frame(v1=c("A cat in sun", "A silver arrow", "A deep sun"), v2=c(1,2,3),stringsAsFactors=F)
其中v1
是要进行对比的文本变量。 DF2
是保存文本链以进行比较的数据框:
DF2 <- data.frame(key = c("arrow|spyder|car", "cat|met|shoe", "sun|moon|earth"), value = c("D","M", "A"), stringsAsFactors=F)
然后,必须使用DF1
中的v1
和来自key
的{{1}}对DF2
中的每一行进行比较,以分配value
。我使用grepl
仅使用以下值进行了测试:
grepl("cat|met|shoe", "A cat in sun")
这样可行,但问题是当我尝试在DF1
内使用相同的逻辑时,结构如下:
DF1$Var <- DF2[grepl(DF2$key, DF1$v1), "value"]
我无法获得预期的结果:
DF3 <- data.frame(v1=c("A cat in sun", "A silver arrow", "A deep sun"), v2=c(1,2,3), Var = c("M", "D", "A"),stringsAsFactors=F)
非常感谢你的帮助。
答案 0 :(得分:0)
希望这有帮助!
df1$Var <- lapply(df1$v1, function(x)
df2[min(which(lapply(df2$key, function(y) grepl(y,x))==T)),"value"])
df1
输出为:
v1 v2 Var
1 A cat in sun 1 M
2 A silver arrow 2 D
3 A deep sun 3 A
示例数据:
df1 <- structure(list(v1 = c("A cat in sun", "A silver arrow", "A deep sun"
), v2 = c(1, 2, 3)), .Names = c("v1", "v2"), row.names = c(NA,
-3L), class = "data.frame")
df2 <- structure(list(key = c("arrow|spyder|car", "cat|met|shoe", "sun|moon|earth"
), value = c("D", "M", "A")), .Names = c("key", "value"), row.names = c(NA,
-3L), class = "data.frame")
答案 1 :(得分:0)
假设您要将第一个value
(例如,M
分配给第一行而由于“cat”而不是A
由于“sun”),那么我们也可以写简单
for(i in nrow(DF2):1)
DF1$value[grep(DF2$key[i], DF1$v1)] <- DF2$value[i]
答案 2 :(得分:0)
我的单线解决方案。
library(fuzzyjoin)
DF1 %>% regex_inner_join(DF2, by = c(v1 = "key")) %>% select(v1,v2,value) %>% filter (! duplicated(v1)) %>% dplyr::rename(Var = value)
<强>结果强>
v1 v2 Var
A cat in sun 1 M
A silver arrow 2 D
A deep sun 3 A