grepl跨多个指定的列

问题描述 投票:4回答:2

我想在我的数据框中创建一个新列,它是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已经寻找其他类似的问题,但似乎没有一个适用于我的情况,我无法适应任何现有的例子。这对我来说是有意义的:

M$China <- mapply(grepl, "CHINA|CHINESE|SINO", x=(M$AB|M$TI)
r grepl
2个回答
5
投票

使用:

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-call返回TRUE / FALSE值的矩阵: AB TI [1,] TRUE FALSE [2,] FALSE TRUE [3,] FALSE FALSE
  • 使用rowSums,您可以检查每行有多少TRUE值。
  • 通过在!!前添加rowSums,您可以将rowSums-call中的所有值从高于零转换为TRUE,将所有值转换为FALSE

1
投票

如果我们需要折叠到一个矢量,使用Map循环列,应用pattern得到listlogical矢量,然后使用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 = .)
© www.soinside.com 2019 - 2024. All rights reserved.