将矩阵列表的列表组合成矩阵列表
Combine list of lists of matrices into a list of matrices
我有一个比较大的列表。列表的每个元素都是六个元素的列表。这些元素中的每一个都是具有固定行数和可变列数的矩阵。我想组合这些矩阵,这样我最终得到一个包含六个矩阵的列表,其中每个矩阵都是对每个子列表中的相应元素调用 cbind 的结果,即第一个矩阵是内部所有第一个矩阵的 cbind列表,第二个矩阵是第二个矩阵的cbind,等等
例如:
temp = list()
temp[["a"]] = list(matrix(1, nrow=2, ncol=1), matrix(2, nrow=2,ncol=2))
temp[["b"]] = list(matrix(3, nrow=2, ncol=3), matrix(4, nrow=2,ncol=4))
*调用一些 R 代码* 应该得到
的输出
$`1`
[,1] [,2] [,3] [,4]
[1,] 1 3 3 3
[2,] 1 3 3 3
$`3`
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 2 2 4 4 4 4
[2,] 2 2 4 4 4 4
我可以看到调用
mapply(cbind, temp[[1]], temp[[2]])
为这个玩具示例生成所需的输出,但我是否为一个大列表执行此操作,从执行到执行可能有可变数量的元素。
是否有一个优雅且高效的解决方案?
提前致谢!
do.call(mapply, c(cbind, temp))
我们可以使用 purrr
和 cbind
中的 transpose
library(purrr)
lapply(transpose(temp), function(x) do.call(cbind, x))
或者我们可以只使用 transpose
和 purrr
中的 map
transpose(temp) %>%
map(~matrix(unlist(.), nrow=2))
#[[1]]
# [,1] [,2] [,3] [,4]
#[1,] 1 3 3 3
#[2,] 1 3 3 3
#[[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 2 2 4 4 4 4
#[2,] 2 2 4 4 4 4
我们也可以尝试 split
选项
library(data.table)
with(melt(temp), lapply(split(value, L1), matrix, nrow=2))
基准
set.seed(24)
lst <- lapply(1:1e5, function(x) replicate(2, matrix(sample(1:5, 10,
replace=TRUE), nrow=2), simplify = FALSE))
system.time({
do.call(mapply, c(cbind, lst))
})
# user system elapsed
# 0.66 0.00 0.65
system.time({
lst %>% pmap(cbind)
})
# user system elapsed
# 0.61 0.00 0.61
system.time({
lapply(transpose(lst), function(x) do.call(cbind, x))
})
# user system elapsed
# 0.39 0.00 0.40
library(microbenchmark)
microbenchmark(Hong = do.call(mapply, c(cbind, lst)),
ae = lst %>% pmap(cbind),
akrun = lapply(transpose(lst), function(x) do.call(cbind, x)),
unit = "relative")
# Unit: relative
# expr min lq mean median uq max neval
# Hong 1.716893 2.346379 1.975948 2.069316 2.012889 1.288478 100
# ae 1.623129 2.096566 1.697061 1.805834 1.702961 1.193930 100
# akrun 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 100
purrr::pmap
并行遍历列表项并传递给您指定的函数,因此您只需
即可获得所需的结果
library(purrr)
temp %>% pmap(cbind)
## [[1]]
## [,1] [,2] [,3] [,4]
## [1,] 1 3 3 3
## [2,] 1 3 3 3
##
## [[2]]
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 2 2 4 4 4 4
## [2,] 2 2 4 4 4 4
我有一个比较大的列表。列表的每个元素都是六个元素的列表。这些元素中的每一个都是具有固定行数和可变列数的矩阵。我想组合这些矩阵,这样我最终得到一个包含六个矩阵的列表,其中每个矩阵都是对每个子列表中的相应元素调用 cbind 的结果,即第一个矩阵是内部所有第一个矩阵的 cbind列表,第二个矩阵是第二个矩阵的cbind,等等
例如:
temp = list()
temp[["a"]] = list(matrix(1, nrow=2, ncol=1), matrix(2, nrow=2,ncol=2))
temp[["b"]] = list(matrix(3, nrow=2, ncol=3), matrix(4, nrow=2,ncol=4))
*调用一些 R 代码* 应该得到
的输出$`1`
[,1] [,2] [,3] [,4]
[1,] 1 3 3 3
[2,] 1 3 3 3
$`3`
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 2 2 4 4 4 4
[2,] 2 2 4 4 4 4
我可以看到调用
mapply(cbind, temp[[1]], temp[[2]])
为这个玩具示例生成所需的输出,但我是否为一个大列表执行此操作,从执行到执行可能有可变数量的元素。
是否有一个优雅且高效的解决方案?
提前致谢!
do.call(mapply, c(cbind, temp))
我们可以使用 purrr
和 cbind
transpose
library(purrr)
lapply(transpose(temp), function(x) do.call(cbind, x))
或者我们可以只使用 transpose
和 purrr
map
transpose(temp) %>%
map(~matrix(unlist(.), nrow=2))
#[[1]]
# [,1] [,2] [,3] [,4]
#[1,] 1 3 3 3
#[2,] 1 3 3 3
#[[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 2 2 4 4 4 4
#[2,] 2 2 4 4 4 4
我们也可以尝试 split
选项
library(data.table)
with(melt(temp), lapply(split(value, L1), matrix, nrow=2))
基准
set.seed(24)
lst <- lapply(1:1e5, function(x) replicate(2, matrix(sample(1:5, 10,
replace=TRUE), nrow=2), simplify = FALSE))
system.time({
do.call(mapply, c(cbind, lst))
})
# user system elapsed
# 0.66 0.00 0.65
system.time({
lst %>% pmap(cbind)
})
# user system elapsed
# 0.61 0.00 0.61
system.time({
lapply(transpose(lst), function(x) do.call(cbind, x))
})
# user system elapsed
# 0.39 0.00 0.40
library(microbenchmark)
microbenchmark(Hong = do.call(mapply, c(cbind, lst)),
ae = lst %>% pmap(cbind),
akrun = lapply(transpose(lst), function(x) do.call(cbind, x)),
unit = "relative")
# Unit: relative
# expr min lq mean median uq max neval
# Hong 1.716893 2.346379 1.975948 2.069316 2.012889 1.288478 100
# ae 1.623129 2.096566 1.697061 1.805834 1.702961 1.193930 100
# akrun 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 100
purrr::pmap
并行遍历列表项并传递给您指定的函数,因此您只需
library(purrr)
temp %>% pmap(cbind)
## [[1]]
## [,1] [,2] [,3] [,4]
## [1,] 1 3 3 3
## [2,] 1 3 3 3
##
## [[2]]
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 2 2 4 4 4 4
## [2,] 2 2 4 4 4 4