申请检查一列中的元素是否按行包含在其他列的列表中

Apply for checking if element in one column is included in list of other column row wise

我想将以下循环转换为 apply/lapply 语法以使其更有效率:

for (i in seq(1, nrow(df)) {
     is.element(df$a[i], unlist(strsplit(df$b[i], "/")))
}

我试过这个:

is.element(df$a, unlist(strsplit(df$b[i], "/")))

但是因为 unlist 语句,它不起作用。

也尝试过:

mapply(is.element, df$a, unlist(strsplit(df$b, "/")))

数据示例:

print(df$a)

[1] "A" "G" "T" "A" "CCG"

print(df$b)

[1] "G/A" "C/TTTTTA" "C/-" "A/G" "G/A/C"

使用 unlist 会递归地将字符串取消列表为单个向量(当我们循环时这没问题,因为只有一个元素)并且比较时可能有不同的 lengtha,而如果我们使用 strsplit 中的 list,则 length 将与 a 相同,而 mapply 要求所有参数都是相同的长度(例外是元素将 length 1 被回收)

mapply(is.element, df$a, strsplit(df$b, "/"))
  A     G     T     A   CCG 
 TRUE FALSE FALSE  TRUE FALSE 

此外,一个更简单的矢量化选项是 str_detect

library(stringr)
str_detect(df$b, df$a)
[1]  TRUE FALSE FALSE  TRUE FALSE

数据

df <- structure(list(a = c("A", "G", "T", "A", "CCG"), b = c("G/A", 
"C/TTTTTA", "C/-", "A/G", "G/A/C")), class = "data.frame", 
row.names = c(NA, 
-5L))

您也可以使用正则表达式:

mapply(\(x, y) grepl(sprintf("/?%s/?", x), y), df$a, df$b)
    A     G     T     A   CCG 
 TRUE FALSE FALSE  TRUE FALSE

或者使用 purrr 包:

map2_lgl(df$a, df$b, ~ any(.x == str_split(.y, "/")[[1]]))
[1]  TRUE FALSE FALSE  TRUE FALSE