【问题标题】:Filter strings across multiple columns with data.table使用 data.table 跨多个列过滤字符串
【发布时间】:2020-12-22 14:29:14
【问题描述】:

我有一个看起来像这样的数据集。

df <- tibble::tribble(
  ~name,           ~x,  ~y,              ~z,  
  "N/A",            1,   "testSmith",    -100, 
  "N A",            3,   "NOt available", -99,
  "test Smith",     NA,  "test Smith",    -98,
  "Not Available", -99, "25",             -101,
  "test Smith",    -98, "28",             -1)

我想创建一个新的 data.table,将所有行都保留为字符串“test”。

最终的数据集应该是这样的

  name           x y              z
  <chr>      <dbl> <chr>      <dbl>
1 N/A            1 testSmith   -100
2 test Smith    NA test Smith   -98
3 test Smith   -98 28            -1

我可以像这样逐列地做这个

setDT(df)[name%like%"test"|y%like%"test"]

这种方法的问题是我有数百个字符串变量,我想找到一种更紧凑的方法。我尝试了以下方法,但它们不起作用

chvar <- keep(trai,is.character)%>%names()
setDT(df)[chvar%like%"test"]#error
setDT(df)[(chvar)%like%"test"]#error
setDT(df)[.(chvar)%like%"test"]#empty dt

有人知道我怎样才能快速有效地做到这一点吗?

非常感谢您的帮助

【问题讨论】:

    标签: r data.table tidyverse


    【解决方案1】:

    data.table 你可以这样做:

    library(data.table)
    
    cols <- c('name', 'y')
    setDT(df)
    
    df[df[, Reduce(`|`, lapply(.SD, `%like%`, "test")), .SDcols = cols]]
    
    #         name   x          y    z
    #1:        N/A   1  testSmith -100
    #2: test Smith  NA test Smith  -98
    #3: test Smith -98         28   -1
    

    在基础 R 中:

    subset(df, Reduce(`|`, lapply(df[cols], function(x) grepl('test', x))))
    

    dplyr

    library(dplyr)
    df %>% filter(Reduce(`|`, across(all_of(cols), ~grepl('test', .x))))
    

    lapply/across 返回所有列的TRUE/FALSE 值列表。如果'test' 存在,它将返回TRUE,如果不存在则返回FALSE。当我们将它与Reduce| 结合使用时,它将只给出TRUE 行中至少有一个TRUE 值。如果行中的所有值都是FALSE,它将返回FALSE。我们只选择那些至少包含一个TRUE 值的行。

    【讨论】:

      【解决方案2】:

      另一个data.table 选项正在使用grepl

      dt[rowSums(dt[, lapply(.SD, grepl, pattern = "test")]) > 0, .SDcols = .(name, y)]
      

      这样

               name   x          y    z
      1:        N/A   1  testSmith -100
      2: test Smith  NA test Smith  -98
      3: test Smith -98         28   -1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-09
        • 2013-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多