2012-04-05 5 views
6

Ich bin auf der Suche nach einer vielseitigen Möglichkeit, von einem data.frame zu einem multidimensionalen Array zu gelangen.Wie bekomme ich einen data.frame in ein mehrdimensionales Array in R?

Ich möchte in der Lage sein, beliebig viele Dimensionen aus beliebig vielen Variablen im Datenrahmen zu erstellen.

Derzeit muss die Methode auf jeden data.frame zugeschnitten werden, Untervermietung erfordert die Bildung eines Vektors.

Ich würde etwas entlang der Schmelze/Gießverfahren in Plyr lieben.

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 
+0

... hätten Sie immer 2 numerische Spalten und dann null oder mehr Faktorspalten? – Tommy

Antwort

7

Sie haben Probleme gehabt können die reshape2 Funktionen für eine etwas subtiler Grund anwenden. Die Schwierigkeit bestand darin, dass Ihr data.frame keine Spalte enthält, mit der Sie steuern können, wie Sie die Elemente entlang der ersten Dimension eines Ausgabearrays anordnen möchten.

Darunter füge ich explizit eine solche Spalte hinzu und nenne sie "row". Mit dieser Funktion können Sie die expressiven Funktionen acast() oder dcast() verwenden, um die Daten beliebig zu verändern.

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 
4

Ich denke, das ist richtig:

array(unlist(lapply(split(data, data$ID), function(x) as.matrix(x[ , c("x", "y")]))), c(10, 2, 2)) 
Verwandte Themen