我想在我的数据框中创建一个新列,它是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)
使用:
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")
在两个AB
和TI
列上循环,并查看该模式的一部分("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
。如果我们需要折叠到一个矢量,使用Map
循环列,应用pattern
得到list
的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 = .)