Comment réorganiser les colonnes data.table (sans copier)

118

Je voudrais colonnes Réorganiser dans mon data.table x, étant donné un vecteur de caractères des noms de colonnes, neworder:

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

Évidemment, je pourrais faire:

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

mais cela nécessiterait de copier à nouveau l'ensemble de données. Y a-t-il une autre façon de faire cela?

Michael
la source

Réponses:

183

Utilisez 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 data.tablelangage courant, toutes les set*fonctions changent leur entrée par référence. Autrement dit, aucune copie n'est effectuée à l'exception de la mémoire de travail temporaire, qui est aussi grande qu'une colonne.

devrait donc être assez efficace. Voir ?setcolorderpour plus de détails.

Chasse
la source
21
Petite précision: setcolorderdéplace les pointeurs de colonne sans utiliser aucune mémoire de travail. Cette phrase sur l'utilisation d'une mémoire de travail aussi grande qu'une colonne est à peu près setkeyvraiment.
Matt Dowle
2
@MatthewDowle - merci pour la clarification. Je pensais que c'était peut-être le cas, mais je n'étais pas sûr à 100%.
Chase le
3
puis-je faire cela pour un sous-ensemble de colonnes? Par exemple, lorsque je veux simplement passer aux colonnes au premier plan?
Peter Pan
5
setcolorder(df, c("someCol",colnames(dt)[!(colnames(dt) %in% c("someCol"))]))
couvert
6
@PeterPan Voir aussi NOUVELLES sur la version de développement 1.10.5 : " setcolorder()accepte désormais moins de ncol(DT)colonnes à déplacer vers l'avant"
Henrik
12

On peut trouver plus facile d'utiliser la solution ci-dessus, mais plutôt trier par numéro de colonne. Par exemple: bibliothèque (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
Stephen
la source
13
Il est généralement déconseillé de faire référence aux colonnes par numéro, dans data.table et ailleurs. La FAQ data.table présente l'argument pour cela dans le premier élément ici: datatable.r-forge.r-project.org/datatable-faq.pdf
Frank