2016-06-20 22 views
3

Angenommen, ich habe eine Liste von Matrizen:Inverse cbind() Funktion R

matrix <- matrix(1:4, nrow = 2, ncol = 2) 
list <- list(matrix, matrix, matrix) 

und eine Matrix von Funktion erstellt cbind():

long.matrix <- do.call(cbind, list) 

     [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 3 1 3 1 3 
[2,] 2 4 2 4 2 4 

Ich möchte den Prozess umzukehren bekommen list von Matrizen aus der long.matrix.

Ich kann es manuell mit der for Schleife tun, aber ich bin auf der Suche nach etwas wie: function(long.matrix, 3), die ich denke, sollte existieren. Gibt es so etwas?

+0

Ganz in der Nähe http://stackoverflow.com/questions/37145863/splitting-a-dataframe-into-equal-parts –

Antwort

5

Brute-Force-Lösung:

f <- function(long.matrix, num) 
      lapply(split(long.matrix, 
         rep(seq(num), each=(ncol(long.matrix)/num)*nrow(long.matrix))), 
        function(x) matrix(x, nrow=nrow(long.matrix)) 
      ) 

f(long.matrix, 3) 
## $`1` 
##  [,1] [,2] 
## [1,] 1 3 
## [2,] 2 4 
## 
## $`2` 
##  [,1] [,2] 
## [1,] 1 3 
## [2,] 2 4 
## 
## $`3` 
##  [,1] [,2] 
## [1,] 1 3 
## [2,] 2 4 

rep baut die Kategorien für split, um die Daten zu teilen. Da R die Kolumne ist, nehmen wir hier die ersten vier, die zweiten vier, die dritten vier Einträge.

in den Werten Füllung für die aktuellen Dimensionen Ihres Beispiel long.matrix und 3 reduziert die Funktion dazu:

lapply(split(long.matrix, rep(seq(3), each=4)), function(x) matrix(x, nrow=2)) 

Hinweis:

(r <- rep(seq(3), each=4)) 
## [1] 1 1 1 1 2 2 2 2 3 3 3 3 
split(long.matrix, r) 
## $`1` 
## [1] 1 2 3 4 
## 
## $`2` 
## [1] 1 2 3 4 
## 
## $`3` 
## [1] 1 2 3 4 

Jede dieser dann zu matrix weitergegeben wird Holen Sie sich das gewünschte Format.

+0

Thank you! Ich bekomme es mehr oder weniger :) Sie denken, dass es so etwas in der Basis R nicht implementiert ist? – cure

+0

@cure Ich glaube nicht, dass es da ist, aber ich würde gerne gezeigt werden, dass es falsch ist. –

+0

Danke für die Lösung! Der Anwer scheint vollständig zu sein. Das wäre der Grund, warum ich keine einfache Lösung finden konnte. Soll ich eine Frage bearbeiten, die es wahrscheinlich nicht gibt und manuell gemacht werden muss? – cure

2

tun:

listm=list() #i=1 
for(i in 1:3)listm[[i]]=long.matrix[,(2*i-1):(i*2)] 

Die lapply Version

lapply(1:3,function(ii)long.matrix[,(2*ii-1):(ii*2)]) 

[[1]] 
    [,1] [,2] 
[1,] 1 3 
[2,] 2 4 

[[2]] 
    [,1] [,2] 
[1,] 1 3 
[2,] 2 4 

[[3]] 
    [,1] [,2] 
[1,] 1 3 
[2,] 2 4 
2

Ich ziehe diese Array-Dimensionen für die Verwendung. Sie können dann eine split Methode für Matrizen definieren:

split.matrix <- function(x, rslice = 1, cslice = 1) { 
    if (ncol(x) %% cslice) stop("cslice not divisor of number of columns") 
    if (nrow(x) %% rslice) stop("rslice not divisor of number of rows") 

    x <- t(x) 
    dim(x) <- c(dim(x)[1], 
       dim(x)[2]/rslice, 
       rslice) 
    x <- lapply(seq_len(rslice), function(k, a) t(a[,,k]), a = x) 

    if (cslice > 1) { 
    x <- lapply(x, function(y, k) { 

     dim(y) <- c(dim(y)[1], 
        dim(y)[2]/k, 
        k) 
     y <- lapply(seq_len(k), function(k, a) a[,,k], a = y) 
     y 
    }, k = cslice) 
    } 
    if(length(x) == 1L) x <- x[[1]] 

    x 
} 

split(long.matrix, 1, 3) 
#[[1]] 
#  [,1] [,2] 
#[1,] 1 3 
#[2,] 2 4 
# 
#[[2]] 
#  [,1] [,2] 
#[1,] 1 3 
#[2,] 2 4 
# 
#[[3]] 
#  [,1] [,2] 
#[1,] 1 3 
#[2,] 2 4 

split(long.matrix, 1, 1) 
#  [,1] [,2] [,3] [,4] [,5] [,6] 
#[1,] 1 3 1 3 1 3 
#[2,] 2 4 2 4 2 4 

split(long.matrix, 2, 1) 

#[[1]] 
#  [,1] [,2] [,3] [,4] [,5] [,6] 
#[1,] 1 3 1 3 1 3 
# 
#[[2]] 
#  [,1] [,2] [,3] [,4] [,5] [,6] 
#[1,] 2 4 2 4 2 4 

split(long.matrix, 2, 3) 
#[[1]] 
#[[1]][[1]] 
#[1] 1 3 
# 
#[[1]][[2]] 
#[1] 1 3 
# 
#[[1]][[3]] 
#[1] 1 3 
# 
# 
#[[2]] 
#[[2]][[1]] 
#[1] 2 4 
# 
#[[2]][[2]] 
#[1] 2 4 
# 
#[[2]][[3]] 
#[1] 2 4