【问题标题】:Sort each column of R data.table对 R data.table 的每一列进行排序
【发布时间】:2018-09-28 16:15:40
【问题描述】:

我正在尝试独立于行结构对 data.table 的列进行排序。我可以用 sapply 和 sort 来做,但我觉得我做的不对——它看起来很慢,而且我需要使用 as.data.table 的事实表明我没有做作业——参考,这是我想要的。有更好的方法吗?这是我的代码:

r <- 10000
c <- 5000

dt <- as.data.table(replicate(c, rnorm(r)))

dt <- as.data.table(sapply(dt,sort))

【问题讨论】:

  • apply(as.matrix(dt),2, sort) 速度较慢......我认为这是自然的基准。
  • 请看我更新的帖子。我认为我的基准测试最初没有正确完成。在第二次迭代中,对于某些情况,列已经排序。我们使用times = 1得到更真实的比较。
  • 知道了——非常感谢!

标签: r sorting data.table


【解决方案1】:

似乎使用 set() 的 for 循环更快(更好?)这是一个基准:

编辑:添加了弗兰克的建议,它似乎击败了我们迄今为止尝试过的任何东西:

编辑 2:更改了 times = 1 以进行更公平的比较 - 原来的解决方案现在看起来不错。

编辑 3:添加了 Hugh 的建议,这似乎是一个改进:

dt <- as.data.table(replicate(c, rnorm(r)))
dt2 <- copy(dt)
dt3 <- copy(dt)
dt4 <- copy(dt)

microbenchmark::microbenchmark(
  set = {for (col in names(dt)) {set(dt, j = col, value = sort(dt[[col]]))}},
  original = as.data.table(sapply(dt2,sort)),
  matrixapply = apply(as.matrix(dt2), 2, sort),
  frank = dt3[, names(dt) := lapply(.SD, sort)],
  hugh = for (j in seq_along(dt4)) { v <- .subset2(dt4, j); set(dt4, j = j, value = v[order(v)]) },
  times = 1
)

结果

Unit: seconds
        expr      min       lq     mean   median       uq      max neval
         set 6.223533 6.223533 6.223533 6.223533 6.223533 6.223533     1
    original 5.598481 5.598481 5.598481 5.598481 5.598481 5.598481     1
 matrixapply 6.039590 6.039590 6.039590 6.039590 6.039590 6.039590     1
       frank 5.255841 5.255841 5.255841 5.255841 5.255841 5.255841     1
        hugh 5.084420 5.084420 5.084420 5.084420 5.084420 5.084420     1

【讨论】:

  • 试试for (j in seq_along(DT)) { v &lt;- .subset2(DT, j) set(DT, j = j, value = v[order(v)]) } DT
猜你喜欢
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-20
  • 1970-01-01
  • 2014-07-26
相关资源
最近更新 更多