如何重新排序data.table列(无需复制)

Mic*_*ael 107 r data.table

data.table x鉴于列名称的字符向量,我想重新排序我的列neworder:

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

显然我可以这样做:

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
Run Code Online (Sandbox Code Playgroud)

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

Cha*_*ase 166

用途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
Run Code Online (Sandbox Code Playgroud)

来自?setcolorder:

data.table说法,所有set*函数都通过引用来改变它们的输入.也就是说,除了临时工作存储器之外,根本不会复制任何副本,而临时工作存储器与一列一样大.

所以应该非常有效率.详情?setcolorder请见.

  • 小澄清:`setcolorder`在不使用任何工作内存的情况下移动列指针.关于使用大到一列的工作内存的那个句子实际上只是关于`setkey`. (18认同)
  • `setcolorder(df,c("someCol",colnames(dt)[!(colnames(dt)%in%c("someCol"))])) (5认同)
  • @PeterPan另请参阅[关于devel版本1.10.5的新闻](https://github.com/Rdatatable/data.table/blob/master/NEWS.md):"`setcolorder()`现在接受少于`ncol (DT)`要移到前面的列" (5认同)
  • 我可以为列的子集执行此操作吗?例如,当我只想移动到前面的列? (3认同)
  • @MatthewDowle - 感谢您的澄清。我有点认为可能是这种情况,但不是 100% 肯定。 (2认同)

Ste*_*hen 9

人们可能会发现使用上述解决方案更容易,而是按列号排序.例如: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
Run Code Online (Sandbox Code Playgroud)

  • 通常不建议在data.table和其他地方按编号引用列.data.table faq在这里的第一个项目中为此创建了参数:http://datatable.r-forge.r-project.org/datatable-faq.pdf (10认同)