在R中计算列表的平均值

3

I have a list with the following structure:

> str(test)
List of 5
$ :List of 2
..$ : num [1:4] 0.0544 0.0839 0.0486 0.043
..$ : num [1:4] 0.0799 0.2434 0.0373 0.2166
$ :List of 2
..$ : num [1:6] 0.938 1.047 1.022 0.689 0.39 ...
..$ : num [1:6] 0.871 0.25 0.824 0.664 0.481 ...
$ :List of 2
..$ : num [1:4] 0.000598 0.000923 0.000535 0.000473
..$ : num [1:4] 0.001039 0.003164 0.000485 0.002816
$ :List of 2
..$ : num [1:6] 0.01032 0.01152 0.01124 0.00758 0.00429 ...
..$ : num [1:6] 0.01133 0.00325 0.01071 0.00864 0.00625 ...
$ :List of 2
..$ : num -0.659
..$ : num -0.962

我想计算每个条目的平均值,即对于第一个条目,我希望:

x <- mean(c(0.0544, 0.0839, 0.0486, 0.043))
y <- mean(c(0.0799, 0.2434, 0.0373, 0.2166)) 

最后,这两个结果的平均值为mean(c(x,y))。
最有效的方法是什么?

4
请查看 lapply 函数。 - coffeinjunky
lapply(test, function(l) sapply(l, mean, na.rm = TRUE))。然后 lapply(result, mean, na.rm = TRUE) - Rui Barradas
rapply 可能是第一个问题最适用的函数。 - Mike H.
5个回答

4

示例数据 - 一个(父)列表中包含(子)列表。

set.seed(1)
foo <- list(
            list(runif(4),runif(4)),
            list(runif(6),runif(6))
           )
#> [[1]]
#> [[1]][[1]]
#> [1] 0.2655087 0.3721239 0.5728534 0.9082078
#> 
#> [[1]][[2]]
#> [1] 0.2016819 0.8983897 0.9446753 0.6607978
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] 0.62911404 0.06178627 0.20597457 0.17655675 0.68702285 0.38410372
#> 
#> [[2]][[2]]
#> [1] 0.7698414 0.4976992 0.7176185 0.9919061 0.3800352 0.7774452

获取每个子列表的方式:
foo_means <- lapply(foo, lapply, mean)
#> [[1]]
#> [[1]][[1]]
#> [1] 0.5296734
#> 
#> [[1]][[2]]
#> [1] 0.6763862
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] 0.3574264
#> 
#> [[2]][[2]]
#> [1] 0.6890909

为了得到每个(父级)列表元素的(子级)平均值的平均值:
lapply(foo_means, function(x) mean(unlist(x)))
#> [[1]]
#> [1] 0.6030298
#> 
#> [[2]]
#> [1] 0.5232587

3

第一个问题似乎是 rapply 的完美应用。使用与 @ngm 的答案中提供的相同样本数据,您可以执行以下操作:

foo2 <- rapply(foo, mean, how = "replace")

foo2
#[[1]]
#[[1]][[1]]
#[1] 0.5296734
#
#[[1]][[2]]
#[1] 0.6763862
#
#
#[[2]]
#[[2]][[1]]
#[1] 0.3574264
#
#[[2]][[2]]
#[1] 0.6890909

1

是的,我知道使用lapply是正确的方法,但是我在处理列表中的列表问题时遇到了一些麻烦...不过,我发现lapply(test, FUN = function(x) {mean(unlist(x))}) 似乎也可以解决问题。 - João Carvalho

1

由于您的列表元素也是列表,因此使用一些嵌套的lapply来获取每个列表的平均值。

lapply(test, function(x) lapply(x, mean))

如果你想将矩阵作为输出,可以这样做:
sapply(test, function(x) sapply(x, mean))

使用sapply,您可以获取每对的平均值
colMeans(sapply(test, function(x) sapply(x, mean, na.rm = TRUE)))

1
你也可以使用 purrr 包中的 modify_depth 函数。参考 @ngm 发布的示例。
library(purrr)

set.seed(1)
foo <- list(list(runif(4), runif(4)),
            list(runif(6), runif(6)))

modify_depth(foo, 2, mean)

#> [[1]]
#> [[1]][[1]]
#> [1] 0.5296734
#> 
#> [[1]][[2]]
#> [1] 0.6763862
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] 0.3574264
#> 
#> [[2]][[2]]
#> [1] 0.6890909

编辑:计算该列表第一级中所有元素的平均值。
modify_depth(foo, 2, mean) %>% 
  map(flatten_dbl) %>% 
  map_dbl(mean)

modify_depth(foo, 2, mean) %>% 
  simplify_all() %>% 
  map_dbl(mean)

[1] 0.60303 0.52326

这段内容是在2018年4月20日使用reprex package (v0.2.0)创建的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接