我们如何对嵌套列表的元素进行列总和。我有一个10的嵌套列表,每个列表包含50个元素的子列表,这些元素是具有4列不同行数的矩阵。这是一个更简单的例子。我需要在列表中添加列。我需要一个colsums.ll< -c(26,66,106,146)的向量。我试着做do.call(" rbind",ll)将列表折叠成1个数据帧然后应用colSums但是没有成功。
l1<-matrix(c(1:8),nrow=2)
l2<-matrix(c(1:16),nrow=4)
l<-list(l1,l2)
ll<-list(l,l)
ll
[[1]]
[[1]][[1]]
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
[[1]][[2]]
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
[[2]]
[[2]][[1]]
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 2 4 6 8
[[2]][[2]]
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
答案 0 :(得分:2)
以下是一些方法:
1)展平ll的第一级,取列和,然后取结果的行和:
rowSums(sapply(do.call(c, ll), colSums))
## [1] 26 66 106 146
2)另一种方法是在展平后将rbind
所有矩阵放在一起然后取colSums
。请注意,与(1)相比,这一个没有sapply
或lapply
。
colSums(do.call(rbind, do.call(c, ll)))
## [1] 26 66 106 146
3)以上不使用任何包但可以翻译为使用magrittr,第一个管道对应于(1),第二个管道对应于(2)
library(magrittr)
ll %>% do.call(what = c) %>% sapply(colSums) %>% rowSums
## [1] 26 66 106 146
ll %>% do.call(what = c) %>% do.call(what = rbind) %>% colSums
## [1] 26 66 106 146
答案 1 :(得分:1)
colSums(do.call(rbind, lapply(lapply(rapply(ll, enquote, how="unlist"), eval), colSums)))
[1] 26 66 106 146
答案 2 :(得分:1)
这是一个purrr选项:
library(purrr)
ll %>% flatten() %>% # reduce depth to one level
map(colSums) %>% # get column sums of each element
reduce(`+`) # add respective colSums
#> [1] 26 66 106 146
首先将其缩小为单个矩阵:
ll %>% flatten() %>% reduce(rbind) %>% colSums()
或使用invoke
而不是reduce
,这会以稍微不那么漂亮的语法为代价来保存来电:
ll %>% flatten() %>% invoke(rbind, .) %>% colSums()
所有回报都是一样的。
答案 3 :(得分:1)
我喜欢基地R中的Reduce
,所以你可以这样做:
Reduce("+", lapply(Reduce(c, ll), colSums))
# [1] 26 66 106 146
<强> BENCHMARKING 强>
set.seed(100)
l1 <- matrix(sample(100, 100000, replace = TRUE),ncol=1000)
l2 <- matrix(sample(100, 1000000, replace = TRUE),ncol=1000)
l <- list(l1,l2)
ll <- rep(list(l), 100)
str(ll)
# List of 100
# $ :List of 2
# ..$ : int [1:100, 1:1000] 31 26 56 6 47 49 82 38 55 18 ...
# ..$ : int [1:1000, 1:1000] 45 22 77 7 85 32 80 71 52 38 ...
# $ :List of 2
# ..$ : int [1:100, 1:1000] 31 26 56 6 47 49 82 38 55 18 ...
# ..$ : int [1:1000, 1:1000] 45 22 77 7 85 32 80 71 52 38 ...
# $ :List of 2
# ..$ : int [1:100, 1:1000] 31 26 56 6 47 49 82 38 55 18 ...
# ..$ : int [1:1000, 1:1000] 45 22 77 7 85 32 80 71 52 38 ...
# $ :List of 2
# ..$ : int [1:100, 1:1000] 31 26 56 6 47 49 82 38 55 18 ...
# ..$ : int [1:1000, 1:1000] 45 22 77 7 85 32 80 71 52 38 ...
library(purrr)
library(microbenchmark)
library(magrittr)
f_G.Grothendieck1 <- function(ll) rowSums(sapply(do.call(c, ll), colSums))
f_G.Grothendieck2 <- function(ll) colSums(do.call(rbind, do.call(c, ll)))
f_G.Grothendieck3 <- function(ll)
ll %>% do.call(what = c) %>% sapply(colSums) %>% rowSums
f_G.Grothendieck4 <- function(ll)
ll %>% do.call(what = c) %>% do.call(what = rbind) %>% colSums
f_d.b <- function(ll)
colSums(do.call(rbind, lapply(lapply(rapply(ll, enquote, how="unlist"), eval), colSums)))
f_alistaire1 <- function(ll) ll %>% flatten() %>% map(colSums) %>% reduce(`+`)
f_alistaire2 <- function(ll) ll %>% flatten() %>% invoke(rbind, .) %>% colSums()
f_989 <- function(ll) Reduce("+", lapply(Reduce(c, ll), colSums))
r <- f_G.Grothendieck1(ll)
# [1] TRUE
all(r == f_G.Grothendieck2(ll))
# [1] TRUE
all(r == f_G.Grothendieck3(ll))
# [1] TRUE
all(r == f_G.Grothendieck4(ll))
# [1] TRUE
all(r == f_d.b(ll))
# [1] TRUE
all(r == f_alistaire1(ll))
# [1] TRUE
all(r == f_alistaire2(ll))
# [1] TRUE
all(r == f_989(ll))
# [1] TRUE
res <- microbenchmark(
f_G.Grothendieck1(ll), f_G.Grothendieck2(ll), f_G.Grothendieck3(ll),
f_G.Grothendieck4(ll), f_d.b(ll), f_alistaire1(ll), f_alistaire2(ll), f_989(ll))
print(res, order="mean")
# Unit: milliseconds
# expr min lq mean median uq max neval
# f_989(ll) 84.67007 87.05084 87.50351 87.70766 88.25692 91.12715 100
# f_alistaire1(ll) 85.00209 87.35116 87.83935 87.91318 88.32242 98.69927 100
# f_d.b(ll) 85.15563 87.74943 88.01660 88.23258 88.72280 89.89943 100
# f_G.Grothendieck1(ll) 85.38729 87.77707 88.40864 88.45328 89.03604 100.78963 100
# f_G.Grothendieck3(ll) 85.85933 87.85805 88.69445 88.68118 89.28618 104.93881 100
# f_G.Grothendieck4(ll) 1150.27718 1200.80601 1205.76164 1206.48442 1211.72250 1310.64802 100
# f_alistaire2(ll) 1178.14509 1202.61153 1207.05208 1205.89009 1211.49820 1325.72315 100
# f_G.Grothendieck2(ll) 1177.02283 1204.55166 1210.40954 1208.95338 1213.82218 1278.82715 100