Jak zmienić kolejność kolumn data.table (bez kopiowania)

118

Chciałbym zmienić kolejność kolumn w moim data.table x, biorąc pod uwagę wektor znaków nazw kolumn neworder:

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

Oczywiście mogłem zrobić:

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

ale wymagałoby to ponownego skopiowania całego zbioru danych. Czy jest inny sposób, aby to zrobić?

Michael
źródło

Odpowiedzi:

183

Zastosowanie 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

Od ?setcolorder:

W data.tableżargonie wszystkie set*funkcje zmieniają swoje dane wejściowe przez odniesienie. Oznacza to, że w ogóle nie jest tworzona żadna kopia poza tymczasową pamięcią roboczą, która ma rozmiar jednej kolumny.

więc powinno być całkiem wydajne. Zobacz ?setcolorderszczegóły.

Pościg
źródło
21
Małe wyjaśnienie: setcolorderprzesuwa wskaźniki kolumn bez użycia pamięci roboczej. To zdanie o używaniu pamięci roboczej tak dużej jak jedna kolumna jest tak setkeynaprawdę.
Matt Dowle,
2
@MatthewDowle - dzięki za wyjaśnienie. Pomyślałem, że tak może być, ale nie byłem w 100% pewien.
Chase
3
czy mogę to zrobić dla podzbioru kolumn? Na przykład, gdy chcę tylko przejść do kolumn na przód?
Peter Pan
5
setcolorder(df, c("someCol",colnames(dt)[!(colnames(dt) %in% c("someCol"))]))
hedgedandlevered
6
@PeterPan Zobacz także WIADOMOŚCI dotyczące wersji rozwojowej 1.10.5 : „ setcolorder()teraz akceptuje mniej niż ncol(DT)kolumny do przeniesienia na wierzch ”
Henrik
12

Powyższe rozwiązanie może być łatwiejsze, ale zamiast tego posortuj dane według numeru kolumny. Na przykład: biblioteka (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
źródło
13
Generalnie odradza się odwoływanie się do kolumn według numeru, w data.table i gdzie indziej. Data.table faq argumentuje za tym w pierwszej pozycji tutaj: datatable.r-forge.r-project.org/datatable-faq.pdf
Frank