Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

dataframe

r

plyr

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
like image 379
Etienne Low-Décarie Avatar asked Apr 05 '12 22:04

Etienne Low-Décarie


People also ask

How do I convert a Dataframe to a matrix in R?

Convert a Data Frame into a Numeric Matrix in R Programming – data. matrix() Function. data. matrix() function in R Language is used to create a matrix by converting all the values of a Data Frame into numeric mode and then binding them as a matrix.

Is Dataframe multi dimensional?

DataFrame s are essentially multidimensional arrays with attached row and column labels, and often with heterogeneous types and/or missing data.


2 Answers

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
like image 59
Josh O'Brien Avatar answered Nov 11 '22 05:11

Josh O'Brien


I think this is right:

array(unlist(lapply(split(data, data$ID), function(x) as.matrix(x[ , c("x", "y")]))), c(10, 2, 2))
like image 40
mdsumner Avatar answered Nov 11 '22 06:11

mdsumner