【问题标题】:How to efficiently apply a reduce-able function on each row of a data.table如何在 data.table 的每一行上有效地应用可归约函数
【发布时间】:2019-03-17 12:41:51
【问题描述】:

考虑一个包含数百万行的大型 data.table 对象dt,如下所示:

     event1 event2 event3 event4 event5
  1:   TRUE  FALSE  FALSE  FALSE  FALSE
  2:   TRUE  FALSE  FALSE  FALSE  FALSE
  3:   TRUE  FALSE  FALSE  FALSE  FALSE
  4:   TRUE  FALSE  FALSE  FALSE  FALSE
  5:   TRUE  FALSE  FALSE  FALSE  FALSE
...

我希望有效地在五列的每一行上应用一个“或”函数。更一般地说,我希望创建一个接收dt 和列名向量cols 的函数,并返回指定列的所需结果。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    使用Reduce 函数(r-base)实现了一个有效的解决方案:

    row_any <- function(dt, cols) {
      return(dt[, Reduce(`|`, .SD), .SDcols=cols])
    }
    

    例如,这里是约 320 万行的时间:

    system.time(res <- row_any(dt, cols))
      user  system elapsed 
      0.028   0.000   0.029 
    

    大多数按行函数的解决方案在边距 1(行)上使用 apply 函数。不建议使用此方法,因为它将.SD 列转换为矩阵,因此放弃了data.table 的效率属性:

    system.time(res2 <- dt[, apply(.SD, 1, any), .SDcols=cols])
      user  system elapsed 
      3.740   0.000   3.747 
    

    这里的关键点是您应该在 data.table 中使用基于向量和列表的函数,而不是将它们转换为矩阵对象。

    【讨论】:

    • do.call(pmax, .SD) 也许。我没有看到示例数据的代码,所以没有测试。
    • 这会稍微慢一些(在同一台机器上经过的时间 = 0.042),但重点是展示了一种可用于未明确设计为“并行”的函数的方法。
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 2016-02-04
    相关资源
    最近更新 更多