2017-04-15 179 views
1

我有一個列表的列表,我想將它轉換成矩陣,使每列=一個子列表。列表到矩陣

莫克例如

list1 <- list(1, 2) 
list2 <- list(1, 2, 3) 
list3 <- list(1, 2, 3, 4) 

list_lists <- list (list1, list2, list3) 

我第一egalizing所有子列表的長度(填充有如果需要空值),以使所有子列表具有最長的一個的長度。這是爲了避免讓R重複數據填充最終矩陣中的行(如果我可以跳過此步驟,請隨意)。

max_length <- max(unlist(lapply (list_lists, FUN = length))) 
list_lists <- lapply (list_lists, function (x) {length (x) <- max_length; return (x)}) 

我最好的嘗試到目前爲止

mat <- lapply (list_lists, cbind) 

mat不看表面像什麼,我想,但實際上並非如此。這不是一個矩陣(並試圖將它轉換成一個使用as.matrix是不成功的),我不能像列表/矩陣一樣引用列/行。

我期待

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

什麼是怪我是

mat <- cbind (list_lists[[1]], list_lists[[2]], list_lists[[3]]) 

似乎工作。我敢打賭,這兩條線是相同的,他們怎麼會有所不同?

回答

1

使用sapply而不是lappy上是這樣的:

list_lists <- sapply (list_lists, function (x) {length (x) <- max_length; return (x)}) 

這應該給你你想要的矩陣。似乎sapply會遞歸地取消列表list_lists中的每個列表,然後應用您指定的函數並將所有輸出包裝到矩陣中,從而有效地繞過上面指定的其他行。

4

他們是不同的,lapply返回一個列表,從摘錄見下文從文檔

使用do.call,而不是mat <- lapply (list_lists, cbind)如下:

mat <- do.call("cbind",list_lists) 

do.call是一樣cbind (list_lists[[1]], list_lists[[2]], list_lists[[3]]),它發生對一系列將成爲數據幀列的列表進行操作。

> do.call("cbind",list_lists) 
    [,1] [,2] [,3] 
[1,] 1 1 1 
[2,] 2 2 2 
[3,] NULL 3 3 
[4,] NULL NULL 4 
> 

理解do.call:

從技術文檔:

do.call構建和執行從名稱的函數調用或 功能和參數列表被傳遞給它。

lapply返回相同的長度爲X,其中的每一個是 施加FUN到

搜索ř控制檯上?do.call?lapply

X的相應元素的結果元素的列表

您還可以閱讀:do.calllapply

1

stri_list2matrix功能應該能夠處理這個問題:

library(stringi) 
stri_list2matrix(list_lists) 
##  [,1] [,2] [,3] 
## [1,] "1" "1" "1" 
## [2,] "2" "2" "2" 
## [3,] NA "3" "3" 
## [4,] NA NA "4" 

另一種方法是使用 「MAX_LENGTH」 創建矩陣:

ml <- max(lengths(list_lists)) 
do.call(cbind, lapply(list_lists, function(x) `length<-`(unlist(x), ml))) 
##  [,1] [,2] [,3] 
## [1,] 1 1 1 
## [2,] 2 2 2 
## [3,] NA 3 3 
## [4,] NA NA 4 

第三種選擇是使用melt從 「reshape2」:

library(reshape2) 
dcast(melt(list_lists), L2 ~ L1) 
## L2 1 2 3 
## 1 1 1 1 1 
## 2 2 2 2 2 
## 3 3 NA 3 3 
## 4 4 NA NA 4