如何对data.table列进行重新排序(不进行复制)


118

data.table x给定列名的字符向量,我想对我的列重新排序neworder

library(data.table)
x <- data.table(a = 1:3, b = 3:1, c = runif(3))
neworder <- c("c", "b", "a")

显然我可以做到:

x[ , neworder, with = FALSE]
# or
x[ , ..neworder]
#            c b a
# 1: 0.8476623 3 1
# 2: 0.4787768 2 2
# 3: 0.3570803 1 3

但这需要再次复制整个数据集。还有另一种方法吗?

Answers:


182

用途setcolorder()

library(data.table)
x <- data.table(a = 1:3, b = 3:1, c = runif(3))
x
#      a b         c
# [1,] 1 3 0.2880365
# [2,] 2 2 0.7785115
# [3,] 3 1 0.3297416
setcolorder(x, c("c", "b", "a"))
x
#              c b a
# [1,] 0.2880365 3 1
# [2,] 0.7785115 2 2
# [3,] 0.3297416 1 3

来自?setcolorder

data.table说法,所有set*功能通过引用改变自己的输入。就是说,除了临时工作存储器(它只有一列)之外,根本不进行任何复制。

因此应该非常有效。有关?setcolorder详细信息,请参见。


21
澄清setcolorder一下:完全不使用任何工作内存就移动列指针。关于使用多达一列的工作内存的那句话setkey确实是真的。
马特·道尔

2
@MatthewDowle-感谢您的澄清。我认为可能是这种情况,但不是100%确定。
Chase 2012年

3
我可以对一部分列执行此操作吗?例如,当我只想移到最前面的列时?
彼得·潘

5
setcolorder(df, c("someCol",colnames(dt)[!(colnames(dt) %in% c("someCol"))]))
树篱danververed

6
@PeterPan另请参见有关devel版本1.10.5的新闻:“ setcolorder()现在接受的ncol(DT)列少于将要移到最前面的列”
Henrik

12

可能会发现使用上述解决方案更容易,但可以按列号进行排序。例如:library(data.table)

    > x <- data.table(a = 1:3, b = 3:1, c = runif(3))
    > x
         a b         c
    [1,] 1 3 0.2880365
    [2,] 2 2 0.7785115
    [3,] 3 1 0.3297416
    > setcolorder(x, c(3,2,1))
    > x
         c         b a
    [1,] 0.2880365 3 1
    [2,] 0.7785115 2 2
    [3,] 0.3297416 1 3

13
通常不建议在data.table和其他地方按数字引用列。data.table常见问题解答在此处的第一项中对此进行了说明:datatable.r-forge.r-project.org/datatable-faq.pdf
Frank
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.