查找跨多个列的值是否存在于字符串中

Find if values across multiple columns are present within a string

我正在尝试确定分布在多个列中的药物名称是否存在于字符串中。我正在使用 str_detect,最终需要引用列索引,因为我不知道我需要使用多少列来搜索。

示例数据:

string.to.search<-c("abc","bc","cd","e","f")
Drug1<-c("b","c","e","f",NA)
Drug2<-c("c","d",NA,NA,NA)
Drug3<-c(NA,NA,NA,NA,NA)

df<-as.data.frame(cbind(string.to.search, Drug1, Drug2, Drug3))

在引用我希望用作搜索词的列(在本例中为 Drug1 到 Drug3)时,我可以很容易地做到这一点,并获得所需的结果:

df.new<-df%>%
  mutate(Found = str_detect(string.to.search, paste(Drug1, Drug2, Drug3, sep="|")))
String.to.search Drug1 Drug2 Drug3 Found
a b c b c TRUE
b c c d TRUE
c d e FALSE
e f FALSE
f FALSE

我发现可以使用列索引,但只能对单个列起作用:

df.new2<-df%>%
  mutate(Found = str_detect(string.to.search, .[[2]]))
String.to.search Drug1 Drug2 Drug3 Found
a b c b c TRUE
b c c d TRUE
c d e FALSE
e f FALSE
f

我不知道如何跨多个列索引进行这项工作,以便我可以从第二列转到最后一列(我可能有 1 种药物,或者将来可能有 10 种)。当我尝试这样做时,出现以下错误:

df.new3<-df%>%
  mutate(Found = str_detect(string.to.search, .[[2:ncol(df)]]))

错误:mutate()Found 有问题。 我Found = str_detect(string.to.search, .[[2:ncol(df)]])。 x 递归索​​引在级别 2

失败

当我只查看 df[2:ncol(df)] 返回的内容时,只有三个 Drug 列按预期返回,所以我觉得我必须使用正确的索引。

非常感谢任何帮助。

如果您的 string.to.search 总是 space 分隔(或容易拆分的内容),那么我们可以使用 %in% 而不是字符串匹配;如果您有子字符串匹配,后者可以提供误报。

df <- structure(list(string.to.search = c("a b c", "b c", "c d", "e", "f"), Drug1 = c("b", "c", "e", "f", NA), Drug2 = c("c", "d", NA, NA, NA), Drug3 = c(NA_character_, NA_character_, NA_character_, NA_character_, NA_character_)), row.names = c(NA, -5L), class = "data.frame")
df
#   string.to.search Drug1 Drug2 Drug3
# 1            a b c     b     c  <NA>
# 2              b c     c     d  <NA>
# 3              c d     e  <NA>  <NA>
# 4                e     f  <NA>  <NA>
# 5                f  <NA>  <NA>  <NA>

df %>%
  mutate(
    Found = Reduce(`|`,
      lapply(subset(., select=Drug1:Drug3),
             function(z) mapply(`%in%`, z, strsplit(string.to.search, " +"))))
  )
#   string.to.search Drug1 Drug2 Drug3 Found
# 1            a b c     b     c  <NA>  TRUE
# 2              b c     c     d  <NA>  TRUE
# 3              c d     e  <NA>  <NA> FALSE
# 4                e     f  <NA>  <NA> FALSE
# 5                f  <NA>  <NA>  <NA> FALSE