2016-06-20 5 views
3

Пусть у меня есть список матриц:Inverse к cbind() функция R

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

и матрица, созданная функция 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 

Я хочу обратить этот процесс, чтобы получить list из матрицы от long.matrix.

Я могу сделать это вручную с помощью цикла for, но я ищу что-то вроде: function(long.matrix, 3), который, как я думаю, должен существовать. Есть такая вещь?

+0

Очень близко к http://stackoverflow.com/questions/37145863/splitting-a-dataframe-into-equal-parts –

ответ

5

решение перебором:

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 строит категории для split, чтобы разделить данные. Поскольку R является основным столбцом, здесь мы берем первые четыре, второй четыре, третий четыре записи.

Заполнение значений для текущих размеров вашего примера long.matrix и 3, функция сводится к этому:

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

Примечание:

(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 

Каждый из тех, затем передается matrix к получите желаемый формат.

+0

Спасибо! Я получаю это более или менее :) Вы думаете, что в базе R нет такой вещи? – cure

+0

@cure Я не думаю, что есть, но я хотел бы, чтобы вас показали, что они неверны. –

+0

Благодарим за решение! Андер кажется полным. Это было бы причиной того, что я не мог найти прямого решения. Должен ли я редактировать вопрос, что он, вероятно, не существует, и его нужно делать вручную? – cure

2

ли это:

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

lapply версия

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

Я предпочитаю использовать размеры массива для этого. Затем вы можете определить метод split для матриц:

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