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 

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

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

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

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

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


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
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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.