Suppose I have a 3-dimensional array g
with dimensions [x,y,z]
. reshape2::melt(g)
would produce a data frame with columns giving indices of x,y,z
and value
where value
contains the values in each entry of the prior array.
Given that reshape2
is superseded, is there a "one function" alternative to the functionality of reshape2::melt
in base R or a more actively supported tidyverse
package that I'm missing?
reshape2
recommends people use tidyr
instead but I can't seem to find solutions to multi-dimensional arrays in tidyr
. There is cubelyr but doesn't seem like that is very active these days either.
I can write a custom solution, just looking for something stable with the easy functionality of reshape2::melt
for this kind of problem
library(reshape2)
g_as_array <- array(rnorm(9), dim = c(3,3,3)) # create a 3D array
g_as_data_frame <- reshape2::melt(g_as_array) # melt down to "tidy" format
head(g_as_data_frame)
#> Var1 Var2 Var3 value
#> 1 1 1 1 1.4092362
#> 2 2 1 1 -2.1606972
#> 3 3 1 1 0.4334404
#> 4 1 2 1 0.2390544
#> 5 2 2 1 -0.9673617
#> 6 3 2 1 0.5668378
Created on 2022-08-25 by the reprex package (v2.0.1)
a <- array(1:27, dim = c(3,3,3))
library(reshape2)
DF1 <- melt(a)
DF2 <- data.frame(
expand.grid(lapply(dim(a), seq_len)),
value = as.vector(a)
)
identical(DF1, DF2)
#[1] TRUE
If the array has dimension names:
a <-array(letters[1:27], dim = c(3, 3, 3), dimnames = list(letters[1:3],
letters[4:6],
letters[7:9]))
library(reshape2)
DF1 <- melt(a)
DF2 <- data.frame(
expand.grid(dimnames(a)),
value = as.vector(a)
)
identical(DF1, DF2)
#[1] TRUE
If not all dimensions have names, you would need to fill in the missing names first, e.g.:
Map(\(x, y) if (is.null(x)) seq_len(y) else x , dimnames(a), dim(a))