【问题标题】:Column names in a list/multi column criteria in data.table Rdata.table R中的列表/多列条件中的列名
【发布时间】:2017-11-24 02:58:54
【问题描述】:

data.table 的新手,所以我一定遗漏了一些明显的东西。

DT <- data.table(a=1:4,b=c(0,1,2,3),c=c(0,2,0,3),d=c(0,3,2,1),e=c(0,8,5,3))
   a b c d e
1: 1 0 0 0 0
2: 2 1 2 3 8
3: 3 2 0 2 5
4: 4 3 3 1 3

我想选择列bcde==0 的行,而不假设我事先知道列名。所以使用colNames &lt;- c('b','c','d','e') 向量。

我试过了

DT[all(DT[,colNames]==0)]

显然无济于事。

欢迎指点!

【问题讨论】:

    标签: r data.table subset


    【解决方案1】:

    我们可以使用Reduce+

    DT[DT[, !Reduce(`+`, lapply(.SD, `!=`, 0)), .SDcols = colNames]]
    #   a b c d e
    #1: 1 0 0 0 0
    

    【讨论】:

    • 很好,因为它可以轻松修改以适应任何条件(与其他解决方案相反,由于我的问题,它专门关注==0
    【解决方案2】:

    DT[,colNames] 尝试从DT 中提取名为colNames 的列。要将colNames作为列名向量,可以使用..colNames,然后使用rowSums逐行检查条件:

    DT[rowSums(DT[, ..colNames] != 0) > 0]
    
    #   a b c d e
    #1: 2 1 2 3 8
    #2: 3 2 0 2 5
    #3: 4 3 3 1 3
    

    如果选择b,c,d,e 列全为零的行:

    DT[rowSums(DT[, ..colNames] != 0) == 0]
    
    #   a b c d e
    #1: 1 0 0 0 0
    

    另外两个选项:

    使用with=FALSE:

    DT[rowSums(DT[, colNames, with=FALSE] != 0) > 0]
    

    或使用mget:

    DT[rowSums(DT[, mget(colNames)] != 0) > 0]
    

    【讨论】:

    • .SDcols - DT[DT[,rowSums(.SD != 0) == 0, .SDcols=colNames],]
    • 感谢您的回答。由于某种原因,.. 运算符在我的情况下不起作用。其余的都可以。将验证第二个答案,因为它更简洁、更通用。
    【解决方案3】:

    为了完整起见,还有一个 data.table 方法使用 join 以编程方式按可变列进行子集:

    library(magrittr) # just for convenience
    # create helper table with selection criteria to join with
    mDT <- colNames %>% length() %>% rep(0, .) %>% as.list() %>% as.data.table() %>% setnames(colNames)
    # join to subset
    DT[mDT, on = names(mDT), nomatch = 0L]
    
       a b c d e
    1: 1 0 0 0 0
    

    帮助表mDT 看起来像:

       b c d e
    1: 0 0 0 0
    

    这种方法也适用于其他mDT,例如,

    mDT <- CJ(a = 3:4, b = 2:3) # cross join
    
       a b
    1: 3 2
    2: 3 3
    3: 4 2
    4: 4 3
    
    DT[mDT, on = names(mDT), nomatch = 0L]
    
       a b c d e
    1: 3 2 0 2 5
    2: 4 3 3 1 3
    

    【讨论】:

      猜你喜欢
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 2022-11-29
      相关资源
      最近更新 更多