【问题标题】:Select ALL Columns | Rows of a data.table based on condition选择所有列 |基于条件的数据表的行
【发布时间】:2016-09-29 05:33:41
【问题描述】:

两个相关问题:

编辑: ps。我正在寻找基于data.table的解决方案。

1.如何为所有列选择超过一定阈值的data.table

2.如何选择data.table中包含的值超过一定阈值?

可重现的例子:

library(data.table)
dt <- data.table(V1=1:5, V2=3:7, V3=7:3)

有条件地选择所有行

# this line selects rows based on column `V1`. 
  dt[ V1 > 2, ] 

# I'm looking for a way to select rows based on values of all columns. My failed attempt
  dt[ names(dt) > 2, ] 

# *expected output*: a data.table with all columns but only with those rows where all values are `> 2` 

#> V1 V2 V3
#> 3  5  5
#> 4  6  4
#> 5  7  3

有条件地选择所有列

# My failed attempt
  dt[, .SD, .SDcols > 2 ]

# *expected output*: a data.table with all rows but only with those columns where all values are `> 2`

#>   V2 V3
#>   3  7
#>   4  6
#>   5  5
#>   6  4
#>   7  3

【问题讨论】:

  • 您的预期输出是什么?我不清楚你想要实现什么。
  • 我在问题中添加了更多信息。够了吗?
  • 谢谢你现在更清楚了:)

标签: r data.table subset


【解决方案1】:

对于子集行,以下代码使用基数 R。因为您是跨行查看,所以您将数据表视为一个矩阵。

rws <- apply(dt, 1L, function(r) any(r > 4))
dt[rws]

对于列,可以再次使用数据表的类似列表的属性:

cls <- sapply(dt, function(c) any(c > 4))
dt[, cls, with = FALSE]

【讨论】:

  • 谢谢@Bazz。我应该明确表示我正在寻找基于data.table. 的解决方案,不过您的回答很有帮助,我相信有些人会觉得它很有用
  • 好的。条件行子集似乎更像是一种矩阵运算。我可以做mtcars[, .SD[apply(.SD &gt; 4, 1L, any)], .SDcols = names(mtcars)],它看起来更像data.table 操作,但mtcars &gt; 4.SD &gt; 4 输出一个矩阵。列子集:mtcars[, .SD[sapply(lapply(.SD, "&gt;", 4), any)], .SDcols = names(mtcars)] 可能,但与上面基本相同。
  • 我现在看到您想要“所有”值 > 4. 用“所有”替换上述代码中的“任何”。
【解决方案2】:

为了获取所有列,但只获取所有值都优于阈值的行,最好的方法是使用经典过滤:

dt[rowMeans(dt>threshold)==1,]

要获取所有行但只获取所有值都优于阈值的列,您可以这样做:

dt[,colMeans(dt>threshold)==1, with=F]

【讨论】:

    【解决方案3】:

    (可选)比rowMeans 复杂得多的解决方案,但提供了更大的灵活性。使用lhs.all 辅助函数回收所提供表达式的LHS 中所有字段的表达式。

    library(data.table)
    dt = data.table(V1=1:5, V2=3:7, V3=7:3)
    
    lhs.all = function(pseudo.expr) {
        sub.pseudo.expr = substitute(pseudo.expr)
        stopifnot(is.call(sub.pseudo.expr), is.character(cols <- eval.parent(sub.pseudo.expr[[2L]])))
        l.expr = lapply(cols, function(x) {
            sub.expr=sub.pseudo.expr
            sub.expr[[2L]] = as.name(x)
            sub.expr
        })
        Reduce(function(a, b) bquote(.(a) & .(b)), l.expr)
    }
    lhs.all(names(dt) > 2)
    #V1 > 2 & V2 > 2 & V3 > 2
    dt[eval(lhs.all(names(dt) > 2))]
    #   V1 V2 V3
    #1:  3  5  5
    #2:  4  6  4
    #3:  5  7  3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-26
      • 2016-10-06
      • 1970-01-01
      • 2020-05-18
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多