【问题标题】:In R, how do you compare two columns with a regex, row-by row?在 R 中,如何将两列与正则表达式逐行进行比较?
【发布时间】:2017-07-13 21:00:23
【问题描述】:

我有一个数据框(实际上是一个小标题)df,有两列,ab,我想过滤掉 ab 的子字符串的行.我试过了

df %>%
  dplyr::filter(grepl(a,b))

但我收到一条警告,似乎表明 R 实际上正在应用 grepl,第一个参数是 wholea

有什么方法可以将涉及两个不同列的正则表达式应用于 tibble(或数据框)中的每一行?

【问题讨论】:

  • 如果您向reproducible example 提供可用于测试的示例输入,则更容易为您提供帮助。但是grepl 没有在模式上进行矢量化。也许使用一些map/Map/mapply 函数来帮助解决这个问题。
  • I get a warning that seems to indicate that R is actually applying grepl with the first argument being the whole column 实际上在这种情况下只使用了第一个元素,而不是整个列。

标签: r regex dplyr


【解决方案1】:

如果您只对逐行比较感兴趣,可以使用rowwise()

df <- data.frame(A=letters[1:5],
             B=paste0(letters[3:7],letters[c(2,2,4,3,5)]),
             stringsAsFactors=F)

df %>% 
   rowwise() %>% 
   filter(grepl(A,B))

       A      B
1      b     db
2      e     ge

------------------------------------------ --------------------------------------
如果你想知道row-entry of A是否在all of B中:

df %>% rowwise() %>% filter(any(grepl(A,df$B)))

      A     B
1     b    db
2     c    ed
3     d    fc
4     e    ge

【讨论】:

    【解决方案2】:

    或者使用 base R apply 和 @Chi-Pak 的可重现示例

    df <- data.frame(A=letters[1:5],
                     B=paste0(letters[3:7],letters[c(2,2,4,3,5)]),
                     stringsAsFactors=F)
    
    matched <- sapply(1:nrow(df), function(i) grepl(df$A[i], df$B[i]))
    
    df[matched, ]
    

    结果

      A  B
    2 b db
    5 e ge
    

    【讨论】:

      【解决方案3】:

      您可以使用stringr::str_detect,它在字符串和模式上进行矢量化。 (然而,正如您所指出的,grepl 仅在其字符串参数上进行矢量化。)

      以@Chi Pak 为例:

      library(dplyr)
      library(stringr)
      
      df %>% 
        filter(str_detect(B, fixed(A)))
      #   A  B
      # 1 b db
      # 2 e ge
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多