Сделайте аргумент `drop` в` dcast` только посмотреть на RHS формулы

Аргумент drop в dcast (из "reshape2" или "dplyr" ) может быть полезен при переходе от "длинного" к "широкому" набору данных, и вы хотите создавать столбцы даже для комбинаций, которые не существуют в длинной форме.

Оказывается, что использование drop также влияет на комбинации левой стороны (LHS) формулы, а также правой стороны (RHS). Таким образом, он также создает дополнительные строки на основе комбинаций значений LHS.

Есть ли способ отменить это поведение?


Вот некоторые примеры данных:

library(data.table)
DT <- data.table(v1 = c(1.105, 1.105, 1.105, 2.012, 2.012, 2.012),
                 ID = c(1L, 1L, 1L, 2L, 2L, 2L), 
                 v2 = structure(c(2L, 3L, 5L, 1L, 2L, 6L), 
                                .Label = c("1", "2", "3", "4", "5", "6"), 
                                class = "factor"),
                 v3 = c(3L, 2L, 2L, 5L, 4L, 3L)) 

Обратите внимание, что "v2" - столбец factor с 6 уровнями. Я, по сути, хочу перейти от "длинного" к широкому ", но добавить столбцы для любых уровней недостающих факторов (в данном случае" 4 ").

reshape обрабатывает форму, но не недостающие столбцы:

reshape(DT, direction = "wide", idvar = c("ID", "v1"), timevar = "v2")
#       v1 ID v3.2 v3.3 v3.5 v3.1 v3.6
# 1: 1.105  1    3    2    2   NA   NA
# 2: 2.012  2    4   NA   NA    5    3

dcast обрабатывает добавление отсутствующих столбцов, но только если в LHS есть одно значение:

dcast(DT, ID ~ v2, value.var = "v3", drop = FALSE)
#    ID  1 2  3  4  5  6
# 1:  1 NA 3  2 NA  2 NA
# 2:  2  5 4 NA NA NA  3

Если в LHS имеется несколько значений, комбинации значений на LHS также расширяются, как если бы мы использовали CJ или expand.grid, но строки 2 и 3 вообще не представляют интереса для я:

dcast(DT, ... ~ v2, value.var = "v3", drop = FALSE)
#       v1 ID  1  2  3  4  5  6
# 1: 1.105  1 NA  3  2 NA  2 NA
# 2: 1.105  2 NA NA NA NA NA NA
# 3: 2.012  1 NA NA NA NA NA NA
# 4: 2.012  2  5  4 NA NA NA  3

Это похоже на использование xtabs в базе R: ftable(xtabs(v3 ~ ID + v1 + v2, DT)).


Есть ли способ, чтобы dcast знал, что по существу: "Привет. Сочетание значений на LHS - это идентификаторы. Не пытайтесь заполнить их для меня".

Мой текущий подход состоит в том, чтобы выполнить три шага: один для свертывания значений LHS, другой для распространения значений RHS, а затем для слияния результата.

merge(DT[, list(v1 = unique(v1)), .(ID)],  ## or unique(DT[, c("ID", "v1"), with = FALSE])
      dcast(DT, ID ~ v2, value.var = "v3", drop = FALSE), 
      by = "ID")[]
#    ID    v1  1 2  3  4  5  6
# 1:  1 1.105 NA 3  2 NA  2 NA
# 2:  2 2.012  5 4 NA NA NA  3

Есть ли лучший подход, который мне не хватает?

Ответы

Ответ 1

Только что реализованный в версии версии data.table версии v.1.9.7, commit 2113, закрывает # 1512.

require(data.table) # v1.9.7, commit 2113+
dcast(DT, ... ~ v2, value.var = "v3", drop = c(TRUE, FALSE))
#       v1 ID  1 2  3  4  5  6
# 1: 1.105  1 NA 3  2 NA  2 NA
# 2: 2.012  2  5 4 NA NA NA  3