跨多个指定列的 grepl

grepl across multiple, specified columns

我想在我的数据框中创建一个新列,该列要么是 TRUE 要么是 FALSE,具体取决于术语是否出现在两个指定的列中。 这是一些示例数据:

AB <- c('CHINAS PARTY CONGRESS','JAPAN-US RELATIONS','JAPAN TRIES TO')
TI <- c('AMERICAN FOREIGN POLICY', 'CHINESE ATTEMPTS TO', 'BRITAIN HAS TEA')
AU <- c('AUTHOR 1', 'AUTHOR 2','AUTHOR 3')
M  <- data.frame(AB,TI,AU)

我可以为一列或另一列执行此操作,但我不知道如何为两者执行此操作。换句话说,我不知道如何将不会相互覆盖的这两行组合起来。

M$China <- mapply(grepl, "CHINA|CHINESE|SINO", x=M$AB)
M$China <- mapply(grepl, "CHINA|CHINESE|SINO", x=M$TI)

我指定列很重要,我不能选择整个 data.frame.I 已经寻找了其他类似的问题,但 none 似乎适用于我的情况,但我一直没能适应任何现有的例子。这对我来说是有意义的:

M$China <- mapply(grepl, "CHINA|CHINESE|SINO", x=(M$AB|M$TI)

使用:

M$China <- !!rowSums(sapply(M[1:2], grepl, pattern = "CHINA|CHINESE|SINO"))

给出:

> M
                     AB                      TI       AU China
1 CHINAS PARTY CONGRESS AMERICAN FOREIGN POLICY AUTHOR 1  TRUE
2    JAPAN-US RELATIONS     CHINESE ATTEMPTS TO AUTHOR 2  TRUE
3        JAPAN TRIES TO         BRITAIN HAS TEA AUTHOR 3 FALSE

这是做什么的:

  • sapply(M[1:2], grepl, pattern = "CHINA|CHINESE|SINO") 遍历 ABTI 两列,并查看模式的一部分 ("CHINA|CHINESE|SINO") 是否存在。
  • sapply-调用returns一个TRUE/FALSE值的矩阵:

            AB    TI
    [1,]  TRUE FALSE
    [2,] FALSE  TRUE
    [3,] FALSE FALSE
    
  • 使用 rowSums 可以检查每行有多少个 TRUE 值。

  • 通过在 rowSums 前面添加 !!,您可以将所有高于零的 rowSums 调用的值转换为 TRUE,并将所有 eros 转换为 FALSE.

如果我们需要折叠成单个向量,使用 Map 遍历列,应用 pattern 得到 list of logical 向量,然后 Reduce 使用 |

将其 logical 向量
M$China <- Reduce(`|`, Map(grepl, "CHINA|CHINESE|SINO", M))
M
#                     AB                      TI       AU China
#1 CHINAS PARTY CONGRESS AMERICAN FOREIGN POLICY AUTHOR 1  TRUE
#2    JAPAN-US RELATIONS     CHINESE ATTEMPTS TO AUTHOR 2  TRUE
#3        JAPAN TRIES TO         BRITAIN HAS TEA AUTHOR 3 FALSE

或在 tidyverse

中使用相同的方法
library(tidyverse)
M %>%
   mutate_all(funs(str_detect(., "CHINA|CHINESE|SINO")))  %>% 
   reduce(`|`) %>%
   mutate(M, China = .)