Bagaimana cara membuat matriks dari daftar vektor di R?

102

Sasaran: dari daftar vektor dengan panjang yang sama, buat matriks di mana setiap vektor menjadi satu baris.

Contoh:

> 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

Saya ingin:

      [,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 
Christopher DuBois
sumber

Jawaban:

124

Salah satu opsinya adalah menggunakan 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
Christopher DuBois
sumber
5
Jadi perbedaan antara this dan standar rbind () adalah bahwa do.call () meneruskan setiap item daftar sebagai argumen terpisah - benarkah? do.call (rbind, a) setara dengan rbind (a [[1]], a [[2]] ... a [[10]])?
Matt Parker
5
do.call () sangat bagus untuk tujuan ini, saya berharap itu lebih baik "didokumentasikan" dalam materi pengantar.
andrewj
16

simplify2arrayadalah fungsi dasar yang cukup intuitif. Namun, karena default R adalah mengisi data berdasarkan kolom terlebih dahulu, Anda perlu mengubah urutan keluarannya. ( sapplypenggunaan simplify2array, seperti yang didokumentasikan di 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
Kalin
sumber
12

Tidak langsung, tetapi berhasil:

> 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
Paolo
sumber
1
Dengan rjsonhasil, colMeanshanya berfungsi untuk metode ini! Terima kasih!
mpyw
10

Fungsi built-in matrixmemiliki opsi yang bagus untuk memasukkan data byrow. Gabungkan dengan unlistpada daftar sumber Anda akan memberi Anda matriks. Kami juga perlu menentukan jumlah baris sehingga dapat memecah data yang tidak terdaftar. Itu adalah:

> 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
Kalin
sumber
Atau mengisi matriks dengan kolom dan kemudian transpos: t( matrix( unlist(a), ncol=length(a) ) ).
Kalin
8
t(sapply(a, '[', 1:max(sapply(a, length))))

dimana 'a' adalah daftar. Akan bekerja untuk ukuran baris yang tidak sama

Arihant
sumber
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
learnr
sumber
1
Ini tidak akan berfungsi jika baris tidak memiliki panjang yang sama, sementara do.call (rbind, ...) masih berfungsi.
pertama
ada petunjuk bagaimana membuatnya bekerja untuk ukuran baris yang tidak sama dengan NA untuk data baris yang hilang?
Arihant
1
@rwst Sebenarnya, do.call (rbind, ...) tidak bekerja untuk vektor yang panjangnya tidak sama, kecuali jika Anda benar-benar bermaksud agar vektor tersebut digunakan kembali saat mengisi baris di akhir. Lihat tanggapan Arihant untuk cara yang mengisi dengan NAnilai di bagian akhir.
Kalin