取消列出具有矩阵元素到矩阵列表的列表

use*_*187 15 r

假设A,B和C是矩阵.我有一个这样的列表:

  list(A,list(B,C))
Run Code Online (Sandbox Code Playgroud)

我想将其转换为:

  list(A,B,C)
Run Code Online (Sandbox Code Playgroud)

unlist函数将矩阵转换为向量!

例如:

A=matrix(1:10,nrow=2)
B=list(A,list(A,A))
unlist(B)
Run Code Online (Sandbox Code Playgroud)

Bro*_*ieG 13

这是一个递归实现:

flatten2 <- function(X) if(is.list(X)) Reduce(c, lapply(X, flatten2)) else list(X)
Run Code Online (Sandbox Code Playgroud)

然后:

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
Run Code Online (Sandbox Code Playgroud)

而且更复杂:

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
Run Code Online (Sandbox Code Playgroud)

此外,一个"更多的"但速度更快的版本(这是皮埃尔测试的版本):

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

你可以flatten2通过替换Reduce来加快一点do.call,但这有点不太可爱. flatten即使有这种变化,仍然是最快的.


MrF*_*ick 12

你可以这样做

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
}
Run Code Online (Sandbox Code Playgroud)

用你的榜样得到

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
Run Code Online (Sandbox Code Playgroud)


And*_*hin 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
Run Code Online (Sandbox Code Playgroud)


Pie*_*une 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
Run Code Online (Sandbox Code Playgroud)

数据

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
Run Code Online (Sandbox Code Playgroud)