如果任何行包含子字符串,则标记

时间:2018-12-02 19:22:37

标签: r

我有一个字符变量数据集:

col1 = c("a","b","c")
col2 = c("a","b_a","d")
df = data.frame(col1,col2)

  col1 col2
1    a    a
2    b  b_a
3    c    d

如果该行中的任何值包含子字符串“ a”,我想创建一个标记为1,0的变量a。

  col1 col2 a
1    a    a 1
2    b  b_a 1
3    c    d 0

我的尝试在下面。它并没有做到这一点,因为我相信如果数据帧中的任何值包含子字符串而不是行都需要TRUE

df["a"] = ifelse(any(sapply(df,function(x) str_detect(x,"a")),TRUE),1,0)

我的想法是,使用ifelse语句,ifelse语句中的任何函数仅求值df[i,]而不是整个数据帧,其中i是它要查找的行在。似乎并非如此。

1)如何构造要查找的数据框?请注意,在我的真实数据集中,有100多个列,因此将它们全部列出没有意义。

2)为什么不只计算i的{​​{1}}行而不是整个df的行?

请注意,前面的问题仅看at one variable,我看的是所有变量,所以这不是重复的。

2 个答案:

答案 0 :(得分:3)

您可以使用

grepl('a', paste0(df$col1, df$col2))

或者概括为任意数量的列

grepl('a',  do.call(paste0, df))

还有第三个选项,如果您要搜索多字符子字符串而不是单个字母,这可能会更安全。在这种情况下,您可能要避免使用paste,例如在向量'ab'中搜索c('xa', 'bx')不会产生误报。在这种情况下,我们可以使用:

substr = 'a'
as.logical(colSums(apply (df, 1, function(x) grepl(substr, x))))

答案 1 :(得分:1)

1)如何构建我要查找的数据框?

df$a <- apply(df,1,function(x) { 
  as.numeric( length(grep("a",x)) > 0) 
  })

输出

  col1 col2 a
1    a    a 1
2    b  b_a 1
3    c    d 0

2)为什么不只评估df的第i行,而不是整个df?

让我们分解一下-

  1. 您正在做sapply(df,function(x) str_detect(x,"a")),这将为您提供-

      col1  col2     a
    

    [1,]是是否 [2,]假真假 [3,] FALSE FALSE FALSE

  2. 接下来,您要做any(sapply(df,function(x) str_detect(x,"a")),TRUE) -这是问题所在。 any未逐行应用,并且输出是单个布尔值。如果要明智地应用any函数行,就可以得到想要的结果。