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