假设A,B和C是矩阵。我有一个这样的列表:
list(A,list(B,C))
我想将其转换为:
list(A,B,C)
unlist
函数将矩阵转换为向量!
例如:
A=matrix(1:10,nrow=2)
B=list(A,list(A,A))
unlist(B)
答案 0 :(得分: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
此外,一个“更多的”但更快的版本(这是皮埃尔测试的版本):
flatten <- function(X) {
res <- list()
for(i in X) res <- c(res, if(is.list(i)) Recall(i) else list(i))
res
}
您可以通过将flatten2
替换为Reduce
来提高do.call
的速度,但这有点不太可爱。 flatten
即使有这种变化,仍然是最快的。
答案 1 :(得分: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
}
用你的例子得到
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
答案 2 :(得分: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
答案 3 :(得分: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