2016-04-04 61 views
3

我有一個嵌套列表的列表。每個嵌套列表的長度都不相同。列表中的每個值都分配了一個名稱。我想從列表中創建一個數據框,但是要對列表進行排序,以便每個值都位於數據框中的正確列中。嵌套列表:將其排序爲一個數據框

很難用英語解釋,我希望這個例子的代碼將解釋:

list <- list(1,1:2,1:3) 
names(list[[1]]) <- "a" 
names(list[[2]]) <- c("c", "a") 
names(list[[3]]) <- c("a","c","b") 

table <- matrix(NA, nrow = 3, ncol = 3) 
colnames(table) <- c("a","b","c") 

> list 
[[1]] 
a 
1 

[[2]] 
c a 
1 2 

[[3]] 
a c b 
1 2 3 

> table 
     a b c 
[1,] NA NA NA 
[2,] NA NA NA 
[3,] NA NA NA 

我想名單整理成表,像這樣:

>table 
      a b c 
list[[1]] 1 NA NA 
list[[2]] 2 NA 1 
list[[3]] 1 3 2 

,這樣的名字列表中的值與表格中列的名稱相匹配,並且list[[1]]轉到第1行,list[[2]]轉到第2行等。

任何幫助都將是應用程序reciated。

(附加信息:

我的實際數據集有數以萬計的嵌套列表中,最長的列表中有26長度

進出口運行32位R 3.2.4在Windows 10)

回答

5

我們可以嘗試smartbind()gtools包與do.call()的組合。

library('gtools') 
do.call("smartbind", list) 
# a c b 
#1 1 NA NA 
#2 2 1 NA 
#3 1 2 3 
+2

我一直在等待這個答案而不知道它一會兒,先生。 +1。 –

+0

哇多麼偉大的功能。謝謝,這工作完美! – llaffin

2

你可以把它們變成數據幀和使用data.table::rbindlist,將在列表

編輯2列出了工作 - 用在rapply作品gtools::smartbind對列表的更復雜的嵌套列表:

list <- list(1,1:2,1:3) 
names(list[[1]]) <- "a" 
names(list[[2]]) <- c("c", "a") 
names(list[[3]]) <- c("a","c","b") 

list <- c(list(list, list(list)), list) 

l <- rapply(list, function(x) data.frame(as.list(x)), how = 'list') 
do.call(gtools::smartbind, l) 

# a c b 
# 1 1 1 3 
# 2 1 1 3 
# 3 1 NA NA 
# 4 2 1 NA 
# 5 1 2 3 

編輯1 - 這個版本可能更有效

list <- list(1,1:2,1:3) 
names(list[[1]]) <- "a" 
names(list[[2]]) <- c("c", "a") 
names(list[[3]]) <- c("a","c","b") 

library('data.table') 
list <- rapply(list, function(x) setDT(as.list(x)), how = 'list') 

# [[1]] 
# a 
# 1: 1 
# 
# [[2]] 
# c a 
# 1: 1 2 
# 
# [[3]] 
# a c b 
# 1: 1 2 3 

rbindlist(list, fill = TRUE)[, c('a','b','c'), with = FALSE] 

# a b c 
# 1: 1 NA NA 
# 2: 2 NA 1 
# 3: 1 3 2 

原創

list <- list(1,1:2,1:3) 
names(list[[1]]) <- "a" 
names(list[[2]]) <- c("c", "a") 
names(list[[3]]) <- c("a","c","b") 

list <- rapply(list, function(x) data.frame(as.list(x)), how = 'list') 

# [[1]] 
# a 
# 1 1 
# 
# [[2]] 
# c a 
# 1 1 2 
# 
# [[3]] 
# a c b 
# 1 1 2 3 

data.frame(data.table::rbindlist(list, fill = TRUE))[, c('a','b','c')] 

# a b c 
# 1 1 NA NA 
# 2 2 NA 1 
# 3 1 3 2 
+0

謝謝!這個答案也適用於我。 – llaffin

+1

@llaffin如果你有一個更復雜的列表列表,比如'list < - c(list(list,list(list)),list)',那麼把這兩個答案結合起來效果很好,即'l < - rapply list,function(x)data.frame(as.list(x)),how ='list'); do.call(gtools :: smartbind,l)'。然而,'rbindlist'不適用於嵌套列表上的廣告 – rawr