如何在另一列中搜索列的每一行

时间:2017-06-26 15:52:15

标签: r

包含许多行的表,但为了简化问题...

> 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中多次出现

2 个答案:

答案 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)])

或者,您可以使用dplyrtidyr。这些创建允许单元格中的多个值的元组,然后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