¿Por qué `stack` no puede funcionar en el resultado de `tapply`?
Suponiendo que tengo un marco de datos df
> dput(df)
estructura(list(x = c("X", "X", "X", "Y", "Y", "Z", "Z", "Z"), y = c("A", "B", "C", "B", "C", "A", "C", "D")), class = "data.frame", row.names = c(NA, -8L))
> df
x y
1 X A
2 X B
3 X C
4 Y B
5 Y C
6 Z A
7 Z C
8 Z D
y generar una lista u1
como se muestra a continuación
u1 <- with(df, tapply(y, x, combn, 2, toString))
donde
> u1
$ X
[1] "A, B" "A, C" "B, C"
$ Y
[1] "B, C"
$ Z
[1] "A, C" "A, D" "C, D"
> str(u1)
List of 3
$ X: chr [1:3(1d)] "A, B" "A, C" "B, C"
$ Y: chr [1(1d)] "B, C"
$ Z: chr [1:3(1d)] "A, C" "A, D" "C, D"
- attr(<em>, "dim")= int 3
- attr(</em>, "dimnames")=List of 1
..$ : chr [1:3] "X" "Y" "Z"
Cuando ejecuto stack(u1)
, obtendré el siguiente error
> stack(u1)
Error in stack.default(u1) : se requiere al menos un elemento del vector
Parece que no puedo utilizar stack
directamente sobre la salida de tapply
, incluso si es una lista con nombres.
Sin embargo, cuando uso u2 <- Map(c, u1)
para el postprocesamiento, las cosas vuelven a funcionar
> u2 <- Map(c, u1)
> u2
$ X
[1] "A, B" "A, C" "B, C"
$ Y
[1] "B, C"
$ Z
[1] "A, C" "A, D" "C, D"
> str(u2)
List of 3
$ X: chr [1:3] "A, B" "A, C" "B, C"
$ Y: chr "B, C"
$ Z: chr [1:3] "A, C" "A, D" "C, D"
> stack(u2)
values ind
1 A, B X
2 A, C X
3 B, C X
4 B, C Y
5 A, C Z
6 A, D Z
7 C, D Z
Como podemos ver, en str(u2)
, los atributos se filtran, lo que parece solucionar el problema.
Mi pregunta es: ¿Por qué falla u1
pero tiene éxito u2
? ¿Hay alguna otra forma en la que pueda usar tapply
sobre u1
sin ningún postprocesamiento (como Map(c, u1)
)?
davy.ai
La razón por la que
stack(u1)
falló es quetapply
crea un arreglo multidimensional con atributos comodim
ydimnames
, que no es compatible constack
. Por otro lado,Map(c, u1)
colapsa las dimensiones y elimina los atributos, convirtiéndolo en una lista regular con nombres questack
puede manejar.Si quieres evitar el procesamiento posterior y mantener los atributos, puedes usar
unlist
con el argumentorecursive = FALSE
para preservar las dimensiones como una lista nombrada:Esto debería producir el mismo resultado que
stack(u2)
.