So ordnen Sie data.table-Spalten neu an (ohne zu kopieren)

118

Ich möchte Spalten in meinem Ordner data.table xmit einem Zeichenvektor aus Spaltennamen neu anordnen neworder:

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

Natürlich könnte ich tun:

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

Dafür müsste jedoch der gesamte Datensatz erneut kopiert werden. Gibt es einen anderen Weg, dies zu tun?

Michael
quelle

Antworten:

181

Verwendung 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

Von ?setcolorder:

Im data.tableSprachgebrauch set*ändern alle Funktionen ihre Eingabe durch Referenz. Das heißt, es wird überhaupt keine Kopie erstellt, außer dem temporären Arbeitsspeicher, der so groß wie eine Spalte ist.

sollte also ziemlich effizient sein. Siehe ?setcolorderfür Details.

Verfolgungsjagd
quelle
21
Kleine Klarstellung: setcolorderVerschiebt die Spaltenzeiger ohne Arbeitsspeicher. Dieser Satz über die Verwendung eines Arbeitsspeichers, der so groß wie eine Spalte ist, ist setkeywirklich.
Matt Dowle
2
@MatthewDowle - danke für die Klarstellung. Ich dachte, das wäre vielleicht der Fall gewesen, war mir aber nicht 100% sicher.
Chase
3
Kann ich das für eine Teilmenge von Spalten tun? Zum Beispiel, wenn ich nur zu Spalten nach vorne wechseln möchte?
Peter Pan
5
setcolorder(df, c("someCol",colnames(dt)[!(colnames(dt) %in% c("someCol"))]))
Hedgedandlevered
6
@ PeterPan Siehe auch NEWS über die Entwicklungsversion 1.10.5 : " Akzeptiertsetcolorder() jetzt weniger als ncol(DT)Spalten, die nach vorne verschoben werden sollen"
Henrik
12

Man kann es einfacher finden, die obige Lösung zu verwenden, sondern stattdessen nach Spaltennummer zu sortieren. Zum Beispiel: Bibliothek (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
quelle
13
Es wird allgemein davon abgeraten, Spalten nach Nummer, in data.table und anderswo zu referenzieren. Die data.table-FAQ liefert das Argument dafür im ersten Punkt hier: datatable.r-forge.r-project.org/datatable-faq.pdf
Frank