R – How to get a data.frame into a multidimensional array in R

dataframeplyrr

I am looking for a more versatile way to get from a data.frame to a multidimensional array.

I would like to be able to create as many dimensions as needed from as many variables in the data frame as desired.

Currently, the method has to be tailored to each data.frame, requires subletting to form a vector.

I would love something along the melt/cast methods in plyr.

   data<-data.frame(coord.name=rep(1:10, 2),
             x=rnorm(20),
             y=rnorm(20),
             ID=rep(c("A","B"), each=10))


    data.array<-array(dim=c(10, 2, length(unique(data$ID))))

    for(i in 1:length(unique(data$ID))){
      data.array[,1,i]<-data[data$ID==unique(data$ID)[i],"x"]
      data.array[,2,i]<-data[data$ID==unique(data$ID)[i],"y"]
    }

data.array
, , 1

      [,1] [,2]
 [1,]    1    1
 [2,]    3    3
 [3,]    5    5
 [4,]    7    7
 [5,]    9    9
 [6,]    1    1
 [7,]    3    3
 [8,]    5    5
 [9,]    7    7
[10,]    9    9

, , 2

      [,1] [,2]
 [1,]    2    2
 [2,]    4    4
 [3,]    6    6
 [4,]    8    8
 [5,]   10   10
 [6,]    2    2
 [7,]    4    4
 [8,]    6    6
 [9,]    8    8
[10,]   10   10

Best Solution

You may have had trouble applying the reshape2 functions for a somewhat subtle reason. The difficulty was that your data.frame has no column that can be used to direct how you want to arrange the elements along the first dimension of an output array.

Below, I explicitly add such a column, calling it "row". With it in place, you can use the expressive acast() or dcast() functions to reshape the data in any way you choose.

library(reshape2)

# Use this or some other method to add a column of row indices.
data$row <- with(data, ave(ID==ID, ID, FUN = cumsum))

m <- melt(data, id.vars = c("row", "ID"))
a <- acast(m, row ~ variable ~ ID)

a[1:3, , ]
# , , A
# 
#   x y
# 1 1 1
# 2 3 3
# 3 5 5
#
# , , B
# 
#   x y
# 1 2 2
# 2 4 4
# 3 6 6