我想将数据框中列的元素与另一个数据帧匹配。
考虑以下数据框:
A=data.frame(par=c('long A story','long C story', 'blabla D'),val=1:3)
B=data.frame(par=c('Z','D','A'),val=letters[1:3])
B列'par'的每个元素应与A列par匹配。 如果匹配,则应在A中标记。 [然后给出一组用于合并A和B的公共值。]
因此,期望的结果是:
A=transform(A,label=c('A','NA','D'))
如何做到这一点?
亨克
答案 0 :(得分:2)
您好,您可以这样做:
list <- lapply(1:length(B$par),function(x) grep(B$par[x],A$par))
list
[[1]]
integer(0)
[[2]]
[1] 3
[[3]]
[1] 1
label <- rep("NA",length(list))
B$par <-as.character(B$par)
label[unlist(list)] <- B$par[which(list != "integer(0)")]
label
[1] "A" "NA" "D"
A <- transform(A,label=label)
A
par val label
1 long A story 1 A
2 long C story 2 NA
3 blabla D 3 D
希望这有帮助。
答案 1 :(得分:2)
我想到的方法:
M <- lapply(strsplit(as.character(A$par), " "), function(x) x[x %in% B$par])
M[sapply(M, function(x) {identical(x, character(0))})] <- NA
A$label <- unlist(M)
A
par val label
1 long A story 1 A
2 long C story 2 <NA>
3 blabla D 3 D
微博在这里给出了答案,结果如下:
Unit: microseconds
expr min lq median uq max
1 EDWARD() 1638.815 1678.934 1698.061 1726.983 4973.823
2 SONAL() 705.348 725.874 734.738 747.334 2085.721
3 TLM() 268.705 281.300 287.831 294.362 1465.744
4 TRINKER() 156.278 168.407 173.538 177.737 1331.391
答案 2 :(得分:1)
要做你想要的,试试
A=data.frame(par=c('long A story','long C story', 'blabla D'),val=1:3)
B=data.frame(par=c('Z','D','A'),val=letters[1:3])
A$label <- NA
for (x in B$par){
is.match <- lapply(A$par,function(y) grep(x, y))
A$label[which(is.match > 0)] <- x
}
(我假设你的意思是你的例子A=transform(a,label=c('A','NA','D'))
中的大写字母A;在这种情况下,这些匹配完全匹配)。编辑:我看到你做了那个编辑。他们确实匹配。
只有恰好有一个B适合每个A时,上述方法才有效(换句话说,对于A可以有多个As,但对于A可以有多个B)。这是因为输出中需要的结构。
答案 3 :(得分:1)
在一个方便的函数中没有循环:
findkey <- function(key,terms) {
result <- sapply(as.character(key),function(x) grepl(x,terms))
result <- apply(result,1,function(x) names(x)[x==TRUE])
result[(lapply(result,length)==0)] <- NA
return(unlist(result))
}
应用于当前示例:
A$label <- findkey(B$par,A$par)
结果:
> A
par val label
1 long A story 1 A
2 long C story 2 <NA>
3 blabla D 3 D