2009-08-25 3 views
88

Цель: из списка векторов равной длины создать матрицу, где каждый вектор станет строкой.Как создать матрицу из списка векторов в R?

Пример:

> a <- list() 
> for (i in 1:10) a[[i]] <- c(i,1:5) 
> a 
[[1]] 
[1] 1 1 2 3 4 5 

[[2]] 
[1] 2 1 2 3 4 5 

[[3]] 
[1] 3 1 2 3 4 5 

[[4]] 
[1] 4 1 2 3 4 5 

[[5]] 
[1] 5 1 2 3 4 5 

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

[[7]] 
[1] 7 1 2 3 4 5 

[[8]] 
[1] 8 1 2 3 4 5 

[[9]] 
[1] 9 1 2 3 4 5 

[[10]] 
[1] 10 1 2 3 4 5 

Я хочу:

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

ответ

110

Одним из вариантов является использование do.call():

> do.call(rbind, a) 
     [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 1 2 3 4 5 
[2,] 2 1 2 3 4 5 
[3,] 3 1 2 3 4 5 
[4,] 4 1 2 3 4 5 
[5,] 5 1 2 3 4 5 
[6,] 6 1 2 3 4 5 
[7,] 7 1 2 3 4 5 
[8,] 8 1 2 3 4 5 
[9,] 9 1 2 3 4 5 
[10,] 10 1 2 3 4 5 
+5

Таким образом, разница между этим и стандартным rbind() является то, что do.call() проходит каждый элемент списка в виде отдельного арг - это правильно? do.call (rbind, a) эквивалентно rbind (a [[1]], a [[2]] ... a [[10]])? –

+1

Насколько я знаю, да. –

+4

do.call() отлично подходит для этой цели, я бы хотел, чтобы во вводных материалах было «документировано». – andrewj

11

не просто, но это работает:

> t(sapply(a, unlist)) 
     [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 1 2 3 4 5 
[2,] 2 1 2 3 4 5 
[3,] 3 1 2 3 4 5 
[4,] 4 1 2 3 4 5 
[5,] 5 1 2 3 4 5 
[6,] 6 1 2 3 4 5 
[7,] 7 1 2 3 4 5 
[8,] 8 1 2 3 4 5 
[9,] 9 1 2 3 4 5 
[10,] 10 1 2 3 4 5 
+0

Обратите внимание, что это не работает для векторов неравной длины. – Kalin

+1

С результатами 'rjson'' 'colMeans' работает только для этого метода! Спасибо! – mpyw

3
> library(plyr) 
> as.matrix(ldply(a)) 
     V1 V2 V3 V4 V5 V6 
[1,] 1 1 2 3 4 5 
[2,] 2 1 2 3 4 5 
[3,] 3 1 2 3 4 5 
[4,] 4 1 2 3 4 5 
[5,] 5 1 2 3 4 5 
[6,] 6 1 2 3 4 5 
[7,] 7 1 2 3 4 5 
[8,] 8 1 2 3 4 5 
[9,] 9 1 2 3 4 5 
[10,] 10 1 2 3 4 5 
+1

Это просто не работает, если строки не имеют одинаковой длины, а do.call (rbind, ...) все еще работает. – rwst

+0

любые подсказки, как заставить его работать для неравного размера строки с NA для недостающих данных строки? – Arihant

+1

@rwst На самом деле do.call (rbind, ...) не работает для векторов неравной длины, если вы действительно не собираетесь использовать вектор повторно при заполнении строки в конце. См. Ответ Arihant для способа, который заполняется значениями 'NA' в конце. – Kalin

5
t(sapply(a, '[', 1:max(sapply(a, length)))) 

где «a» - это список. Работает для неравных размеров ряда

7

Функция matrix имеет хорошую возможность ввести данные byrow. Объедините, что с unlist в вашем исходном списке даст вам матрицу. Нам также необходимо указать количество строк, чтобы они могли разбить данные, не включенные в список. То есть:

> matrix(unlist(a), byrow=TRUE, nrow=length(a)) 
     [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 1 2 3 4 5 
[2,] 2 1 2 3 4 5 
[3,] 3 1 2 3 4 5 
[4,] 4 1 2 3 4 5 
[5,] 5 1 2 3 4 5 
[6,] 6 1 2 3 4 5 
[7,] 7 1 2 3 4 5 
[8,] 8 1 2 3 4 5 
[9,] 9 1 2 3 4 5 
[10,] 10 1 2 3 4 5 
+0

Или заполнить матрицу по столбцам и затем транспонировать: 't (матрица (unlist (a), ncol = length (a)))'. – Kalin

11

simplify2array - это базовая функция, которая довольно интуитивно понятна. Однако, поскольку по умолчанию R поначалу заполняет данные по столбцам, вам нужно будет транспонировать результат. (sapply использует simplify2array, как описано в help(sapply).)

> t(simplify2array(a)) 
     [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 1 2 3 4 5 
[2,] 2 1 2 3 4 5 
[3,] 3 1 2 3 4 5 
[4,] 4 1 2 3 4 5 
[5,] 5 1 2 3 4 5 
[6,] 6 1 2 3 4 5 
[7,] 7 1 2 3 4 5 
[8,] 8 1 2 3 4 5 
[9,] 9 1 2 3 4 5 
[10,] 10 1 2 3 4 5 
Смежные вопросы