2015-07-11 137 views

回答

13

這裏是一個遞歸實現:

flatten2 <- function(X) if(is.list(X)) Reduce(c, lapply(X, flatten2)) else list(X) 

然後:

str(flatten2(B)) # list of three matrices: 
# List of 3 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 

和更復雜:

C <- list(A, list(list(A, A), A)) 
str(flatten2(C)) 
# List of 4 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 

另外, 「wordier」,但更快的版本(這是P測試的版本) ierre):

flatten <- function(X) { 
    res <- list() 
    for(i in X) res <- c(res, if(is.list(i)) Recall(i) else list(i)) 
    res 
} 

你也可以將flatten2快一點用do.call更換Reduce,但畢竟是少一點可愛。即使有這種變化,flatten仍然是最快的。

+0

您的解決方案可能是最快的。 –

11

你可以做這樣的事情

delist<-function(x) { 
    lists <- sapply(x, class)=="list" 
    while(any(lists)) { 
     x<-mapply(function(y,z) if (!z) list(y) else (y), x, lists, SIMPLIFY=FALSE) 
     x<-do.call('c', x) 
     lists <- sapply(x, class)=="list" 
    } 
    x 
} 

你的榜樣你

delist(B) 
# [[1]] 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 1 3 5 7 9 
# [2,] 2 4 6 8 10 
# 
# [[2]] 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 1 3 5 7 9 
# [2,] 2 4 6 8 10 
# 
# [[3]] 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 1 3 5 7 9 
# [2,] 2 4 6 8 10 
+0

我不知道這是否會作調整,與嵌套像'B =列表的額外級別(A,列表(A工作,列表(A)))' –

+1

@PierreLafortune我已更新添加'SIMPLIFY = FALSE',現在應該使您的示例輸入工作。這可以防止造成問題的不希望的簡化。 – MrFlick

+1

或者你可以使用'Map'! ;)(+1) – BrodieG

7

可以使用rlist包的list.flatten功能。舉個例子:

library(rlist) 
A1 <- matrix(1:10, nrow = 2) 
A2 <- matrix(11:20, nrow = 2) 
A3 <- matrix(21:30, nrow = 2) 
B <- list(A1, list(A2, A3)) 
C <- list.flatten(B) 

C  
# [[1]] 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 1 3 5 7 9 
# [2,] 2 4 6 8 10 
# 
# [[2]] 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 11 13 15 17 19 
# [2,] 12 14 16 18 20 
# 
# [[3]] 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] 21 23 25 27 29 
# [2,] 22 24 26 28 30 

str(C)  
# List of 3 
# $ : int [1:2, 1:5] 1 2 3 4 5 6 7 8 9 10 
# $ : int [1:2, 1:5] 11 12 13 14 15 16 17 18 19 20 
# $ : int [1:2, 1:5] 21 22 23 24 25 26 27 28 29 30 
+1

什麼是一個有趣的包。 +1有用的信息 –

+0

@PierreLafortune,這是我最喜歡的工作列表。 – AndreyAkinshin

5

這麼多很棒的解決方案。我想貢獻一個比較:

library(microbenchmark) 
microbenchmark(
    flatten = flatten(lst), 
    delist = delist(lst), 
    list.flatten = list.flatten(lst)) 
#   expr  min  lq  mean median  uq 
#  flatten 14.606 16.3830 19.17356 17.7640 18.5540 
#  delist 228.559 239.6115 251.52930 247.5070 254.0205 
# list.flatten 51.318 56.0545 63.87871 61.7785 70.2660 
#  max neval 
# 41.449 100 
# 406.589 100 
# 145.267 100 

數據

A <- matrix(1e4, 100) 
lst <- list(A, list(A, list(A, list(A, list(A, list(A, list(A))))))) 
flatten <- function(X) { 
    res <- list() 
    for(i in X) res <- c(res, if(is.list(i)) Recall(i) else list(i)) 
    res 
} 

delist<-function(x) { 
    lists <- sapply(x, class)=="list" 
    while(any(lists)) { 
     x<-mapply(function(y,z) if (!z) list(y) else (y), x, lists, SIMPLIFY=FALSE) 
     x<-do.call('c', x) 
     lists <- sapply(x, class)=="list" 
    } 
    x 
} 
library(rlist) 
list.flatten