Cómo reordenar las columnas de data.table (sin copiar)


118

Me gustaría columnas de reabastecimiento en mi data.table x, dado un vector de caracteres de nombres de columna, neworder:

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

Obviamente podría hacer:

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

pero eso requeriría copiar todo el conjunto de datos nuevamente. Hay otra manera de hacer esto?

Respuestas:


183

Utilizar 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

De ?setcolorder:

En el data.tablelenguaje, todas las set*funciones cambian su entrada por referencia. Es decir, no se realiza ninguna copia, excepto la memoria de trabajo temporal, que es tan grande como una columna.

por lo que debería ser bastante eficiente. Consulte ?setcolorderpara obtener más detalles.


21
Pequeña aclaración: setcolordermueve los punteros de las columnas sin utilizar ninguna memoria de trabajo. Esa frase sobre el uso de la memoria de trabajo tan grande como una columna es casi setkeyreal.
Matt Dowle

2
@MatthewDowle: gracias por la aclaración. En cierto modo pensé que ese podría haber sido el caso, pero no estaba 100% seguro.
Chase

3
¿Puedo hacer eso para un subconjunto de columnas? Por ejemplo, ¿cuando solo quiero moverme a las columnas del frente?
Peter Pan

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

6
@PeterPan Vea también NOTICIAS sobre la versión de desarrollo 1.10.5 : " setcolorder()ahora acepta menos de ncol(DT)columnas para ser movidas al frente"
Henrik

12

A uno le puede resultar más fácil usar la solución anterior, pero en su lugar ordenar por número de columna. Por ejemplo: biblioteca (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
En general, no se recomienda hacer referencia a las columnas por número, en data.table y en otros lugares. El faq data.table presenta el argumento para esto en el primer elemento aquí: datatable.r-forge.r-project.org/datatable-faq.pdf
Frank
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.