包含许多行的表,但为了简化问题...
> df <- data.frame(V1=c("dfafddf","B,C:Moll,A","","a bA.Capple","","adfadew"),
V2=c("1","2","3","4","5","6"),
V3=c("apple","Moll","nancy","NA","NA","NA"))
V1 V2 V3
1 dfafddf 1 apple
2 B,C:Moll,A 2 Moll
3 3 nancy
4 a bA.Capple 4 NA
5 5 NA
6 adfadew 6 NA
所以我要做的是在V1列中搜索V3列并创建一个V2的新列,其中V3在V1中找到。
例如,第4行发现V3的苹果,第2行发现Moll。所以,
所需的输出看起来像
V1 V2 V3 V4
1 dfafddf 1 apple 4
2 B,C:Moll,A 2 Moll 2
3 3 nancy NA
4 a bA.Capple 4 NA NA
5 5 NA NA
6 adfadew 6 NA NA
我已尝试过以下内容,但不会给我预期的结果。
transform(df, V4=mapply(grepl, pattern=df$V3, x=df$V1)
注意: V3可以在V1中多次出现
答案 0 :(得分:1)
应该这样做......
df$V4 <- sapply(df$V3,function(x) df$V2[grep(x,df$V1)[1]])
df
V1 V2 V3 V4
1 dfafddf 1 apple 4
2 B,C:Moll,A 2 Moll 2
3 3 nancy NA
4 a bA.Capple 4 NA NA
5 5 NA NA
6 adfadew 6 NA NA
如果V1中有多个匹配,则上面的代码返回与第一个匹配的V2值。
要获得所有匹配,最好将其保存为单独的列表,否则您可能在数据框中嵌套了单元格,这可能会变得混乱!...
allMatches <- lapply(df$V3,function(x) df$V2[grep(x,df$V1)])
或者,您可以使用dplyr
和tidyr
。这些创建允许单元格中的多个值的元组,然后tidyr
函数unnest
将传播它们以为每个值创建单独的行。所以......就像......
library(dplyr)
library(tidyr)
df2 <- df %>% mutate(V4=lapply(V3, function(x) df$V2[grep(x,df$V1)])) %>% unnest(V4)
出于某种原因,这会丢弃V3为NA
的行,但它至少会以整齐的格式为您提供所需的结果。
您可以使用
在基础R中实现类似的功能lst <- lapply(df$V3,function(x) df$V2[grep(x,df$V1)])
names(lst)<-df$V3
as.data.frame(stack(lst))
答案 1 :(得分:1)
为了简化问题,
a<-letters[1:26]#a,b,c...z
b<-letters[1:13]#a,b,c...m
b[b %in% a]#the elements of b contained in a