提问人:domath 提问时间:8/1/2023 更新时间:8/1/2023 访问量:83
R 中的嵌套列表的平均值
Average a nested list in R
问:
我有类似于以下示例的列表
example <- list(
list(A = 10, B = list(H = 110, E = 211, G = c(1.4,2)), C = c(13,24)),
list(A = 15, B = list(H = 100, E = 201, G = c(0.1,5)), C = c(11,25)),
list(A = 5, B = list(H = 101, E = 221, G = c(1.2,3)), C = c(14,21))
)
这些列表的形状相同,并且都是数字。我想对它们进行元素平均,并将平均值保存在同一个列表中
list(A = . , B = list(H = . , E = . , G = c(.,.)), C = c(.,.)),
答:
4赞
Allan Cameron
8/1/2023
#1
您可以编写一个简单的单行递归函数,将两个结构相同的列表的并行成员连接起来,将列表作为操作数调用此函数,然后得到均值:Reduce
rapply
example <- list(
list(A = 10, B = list(H = 110, E = 211, G = c(1.4,2)), C = c(13,24)),
list(A = 15, B = list(H = 100, E = 201, G = c(0.1,5)), C = c(11,25)),
list(A = 5, B = list(H = 101, E = 221, G = c(1.2,3)), C = c(14,21))
)
f <- function(a, b) if(is.list(a)) Map(f, a, b) else rbind(a, b)
rapply(Reduce(f, example), colMeans, how = "list")
#> $A
#> [1] 10
#>
#> $B
#> $B$H
#> [1] 103.6667
#>
#> $B$E
#> [1] 211
#>
#> $B$G
#> [1] 0.900000 3.333333
#>
#>
#> $C
#> [1] 12.66667 23.33333
创建于 2023-07-31,使用 reprex v2.0.2
2赞
Stéphane Laurent
8/1/2023
#2
这是一种方法,但不确定它是否适合您的实际问题。
library(rlist) # to use list.unzip
example <- list(
p1 = list(A = 10, B = list(H = 110, E = 211, G = c(1.4,2)), C = c(13,24)),
p2 = list(A = 15, B = list(H = 100, E = 201, G = c(0.1,5)), C = c(11,25)),
p3 = list(A = 5, B = list(H = 101, E = 221, G = c(1.2,3)), C = c(14,21))
)
u <- list.unzip(example)
u$B <- apply(u$B, 1L, simplify2array)
Mean <- function(x) {
if(is.matrix(x)) {
rowMeans(x)
} else {
mean(x)
}
}
rapply(u, Mean, how = "replace")
# $A
# [1] 10
#
# $B
# $B$H
# [1] 103.6667
#
# $B$E
# [1] 211
#
# $B$G
# [1] 0.900000 3.333333
#
#
# $C
# [1] 12.66667 23.33333
2赞
Joris C.
8/1/2023
#3
另一种方法是使用 (在包中 ) 将嵌套列表解嵌到一个宽的 data.frame 中,之后我们可以计算 data.frame 各列的平均值。要将结果转换回嵌套列表,我们可以使用(如有必要)。rrapply()
rrapply
relist()
library(rrapply)
## return single-layer list
(result <- rrapply(example, how = "bind") |>
apply(2, \(x) Reduce("+", x) / length(x)))
#> $A
#> [1] 10
#>
#> $B.H
#> [1] 103.6667
#>
#> $B.E
#> [1] 211
#>
#> $B.G
#> [1] 0.900000 3.333333
#>
#> $C
#> [1] 12.66667 23.33333
## return nested list
relist(unlist(result), skeleton = example[[1]])
#> $A
#> [1] 10
#>
#> $B
#> $B$H
#> [1] 103.6667
#>
#> $B$E
#> [1] 211
#>
#> $B$G
#> [1] 0.900000 3.333333
#>
#>
#> $C
#> [1] 12.66667 23.33333
评论