Транспонирование data.table с помощью reshape2:::dcast

Я перевожу data.table и решил использовать reshape2:::dcast, однако меня мучает странная обработка data.table... вот игрушечный набор данных, который копирует поведение:

> library(data.table)
> library(reshape2)
> DT <- structure(list(STORE = c(32123L, 32469L, 33177L, 33484L, 34772L, 34875L), 
                       VOLUME = c(343.87205, 599.78335, 1665.90895, 712.0343, 465.6489, 622.5189)), 
                       .Names = c("STORE", "VOLUME"), 
                       sorted = "STORE", 
                       class = c("data.table", "data.frame"), 
                       row.names = c(NA, -6L))
> (R1 <- dcast(DT, . ~ STORE, value.var = "VOLUME"))
  .    32123    32469    33177    33484    34772    34875
1 . 343.8721 599.7834 1665.909 712.0343 465.6489 622.5189

Отлично, именно так, как я хочу, чтобы это выглядело (отбрасывая . столбец не важен) - но он больше не классифицируется как data.table:

> class(R1)
[1] "data.frame"

Я попытался явно вызвать метод для data.tables в пакете data.table, но R теперь не нравится формула:

> data.table:::dcast.data.table(DT, . ~ STORE, value.var = "VOLUME")
Error in data.table:::dcast.data.table(DT, . ~ STORE, value.var = "VOLUME") : 
  LHS of formula evaluates to 'character(0)', invalid formula.
2: stop("LHS of formula evaluates to 'character(0)', invalid formula.")
1: data.table:::dcast.data.table(DT, . ~ STORE, value.var = "VOLUME")

Это можно легко обойти, создав фиктивный столбец, который будет удален после транспонирования:

> DT[, "dummy" := NA]
> (R2 <- data.table:::dcast.data.table(DT, dummy ~ STORE, value.var = "VOLUME"))
   dummy    32123    32469    33177    33484    34772    34875
1:    NA 343.8721 599.7834 1665.909 712.0343 465.6489 622.5189
> class(R2)
[1] "data.table" "data.frame"

Однако тот факт, что data.table:::dcast.data.table не было обработки для NULL LHS формулы приведения, заставляет меня поверить, что я все об этом ошибаюсь - есть ли способ "data.table" сделать это?

1 ответ

Решение

В data.table вам не нужен dcast для того, чтобы выполнить изменение, которое вам нужно. Просто использовать

 DT[, as.list(setNames(VOLUME, STORE))]

Объяснение:

В [.data.tableесли j выражение (т.е. DT[i, j]) это list, список рассматривается как столбцы вывода.
Имена списка принимаются за имена столбцов (пропущенные имена заполняются V*)

например:

  DT[, j= list(ABC=123, greetings="Hello World", 1, alpha = 0.9995)]
  #    ABC   greetings V3  alpha
  # 1: 123 Hello World  1 0.9995

Таким образом, в решении:

  • setnNames (base R функция. Не путать с setnames от data.table пакет) применяет один вектор в качестве имен другого.
  • преобразование вектора в list говорит [.data.table рассматривать их как столбцы.

(в качестве альтернативы, вы можете просто сохранить его как именованный вектор, если это то, что вам нужно для ваших целей)


проблема с дкастами

Что касается разницы между reshape2::dcast а также dcast.data.tableКак отмечает @David Arenburg в комментариях выше, это было решено в версии devel data.table на github и будет на CRAN с V1.9.6

library (devtools)
install_github("Rdatatable/data.table")
Другие вопросы по тегам