r - div - tags$style shiny
Haga que el argumento `drop` en` dcast` solo mire el RHS de la fórmula (1)
El argumento drop
en dcast
(de "reshape2" o "dplyr") puede ser útil cuando se pasa de un conjunto de datos "largo" a un "ancho" y desea crear columnas incluso para combinaciones que no existen en la forma larga.
Resulta que el uso de la drop
también afecta a las combinaciones del lado izquierdo (LHS) de la fórmula, así como del lado derecho (RHS). Por lo tanto, también crea filas adicionales basadas en las combinaciones de valores LHS.
¿Hay una manera de anular este comportamiento?
Aquí hay algunos datos de muestra:
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))
Observe que "v2" es una columna de factor
con 6 niveles. Básicamente quiero pasar de "largo" a ancho ", pero agregar columnas para los niveles de factor faltantes (en este caso" 4 ")
reshape
maneja la forma, pero no las columnas que faltan:
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
encarga de agregar las columnas que faltan, pero solo si hay un valor en el 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
Si hay varios valores en el LHS, las combinaciones de los valores en el LHS también se expanden, como si hubiéramos usado CJ
o expand.grid
, pero las filas 2 y 3 no me interesan en absoluto:
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
Esto es similar a usar xtabs
en base R: ftable(xtabs(v3 ~ ID + v1 + v2, DT))
.
¿Hay una manera de que dcast
sepa que, en esencia, "Oye. La combinación de valores en el LHS son las ID. No intentes completarlas por mí".
Mi enfoque actual es hacer tres pasos, uno para colapsar los valores de LHS, otro para distribuir los valores de RHS y luego uno para fusionar el resultado.
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
¿Hay un mejor enfoque que me falta?
Acaba de implementarse en la versión de desarrollo de data.table v1.9.7, commit 2113 , cierra #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