排序R data.table的每一列

时间:2018-09-28 16:15:40

标签: r sorting data.table

我试图独立于行结构对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))

1 个答案:

答案 0 :(得分:3)

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

编辑:添加了弗兰克(Frank)的建议,它似乎超出了我们到目前为止尝试过的所有内容:

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

编辑3 :添加了休的建议,似乎有所改进:

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