将具有矩阵元素的列表的列表取消为列表矩阵
问题描述:
假设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)
答
这里是一个递归实现:
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
仍然是最快的。
答
你可以做这样的事情
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
答
可以使用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
答
这么多很棒的解决方案。我想贡献一个比较:
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
您的解决方案可能是最快的。 –