Как изменить порядок столбцов data.table (без копирования)

118

Я хотел бы изменить порядок столбцов в моем data.table x, учитывая вектор символов имен столбцов neworder:

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

Очевидно, я мог:

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

но это потребует повторного копирования всего набора данных. Есть другой способ сделать это?

Майкл
источник

Ответы:

183

Использование 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

Откуда ?setcolorder:

В data.tableпросторечии, все set*функции изменяют свой вклад в виде ссылки. То есть копирование не производится вообще, за исключением временной рабочей памяти, размер которой равен одному столбцу.

так должно быть довольно эффективно. Подробнее ?setcolorderсм.

гнаться
источник
21
Небольшое уточнение: setcolorderперемещает указатели столбцов без использования какой-либо рабочей памяти. Это предложение об использовании рабочей памяти размером с один столбец почти setkeyдействительно.
Мэтт Доул,
2
@MatthewDowle - спасибо за разъяснения. Я как бы думал, что это могло быть так, но не был уверен на 100%.
Чейз
3
могу я сделать это для подмножества столбцов? Например, когда я просто хочу перейти к столбцам на передний план?
Питер Пэн
5
setcolorder(df, c("someCol",colnames(dt)[!(colnames(dt) %in% c("someCol"))]))
hedgedandlevered
6
@PeterPan См. Также НОВОСТИ о разрабатываемой версии 1.10.5 : « setcolorder()теперь принимает меньше ncol(DT)столбцов, которые нужно переместить на передний
Хенрик
12

Возможно, будет проще использовать приведенное выше решение, но вместо этого выполните сортировку по номеру столбца. Например: библиотека (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
Обычно не рекомендуется ссылаться на столбцы по номерам, в data.table и в других местах. В часто задаваемых вопросах data.table приводится аргумент в пользу этого в первом элементе здесь: datatable.r-forge.r-project.org/datatable-faq.pdf
Фрэнк