Calculate means across elements in a list

偶尔善良 提交于 2019-12-11 01:48:02

问题


I have a list like this:

(mylist <- list(a = data.frame(x = c(1, 2), y = c(3, 4)),
                b = data.frame(x = c(2, 3), y = c(4, NA)),
                c = data.frame(x = c(3, 4), y = c(NA, NA))))
$a
  x y
1 1 3
2 2 4

$b
  x  y
1 2  4
2 3 NA

$c
  x  y
1 3 NA
2 4 NA

which is created by purrr::map(). How can I calculate the means of values in the corresponding cells? i.e.

  x   y
1 2 3.5
2 3   4

where

mean(c(1,  2,  3), na.rm = T) # = 2
mean(c(2,  3,  4), na.rm = T) # = 3
mean(c(3,  4, NA), na.rm = T) # = 3.5
mean(c(4, NA, NA), na.rm = T) # = 4

Thanks for your help!


回答1:


A purrr option

library(purrr)
map_df(transpose(mylist), ~rowMeans(as.data.frame(.x), na.rm = TRUE))
 # A tibble: 2 x 2
#      x     y
#  <dbl> <dbl>
#1     2   3.5
#2     3   4  



回答2:


One method would be to convert your list to an array, and then to apply the mean function across the third dimension of the array:

my_array <- array(unlist(mylist), dim=c(2,2,3))
apply(my_array, c(1,2), mean, na.rm=T)

#      [,1] [,2]
# [1,]    2  3.5
# [2,]    3  4.0

If you wanted to do this all in one shot, without hard-coding the dimensions, you could do:

apply(array(unlist(mylist), dim=c(nrow(mylist[[1]]),ncol(mylist[[1]]),length(mylist))), c(1,2), mean, na.rm=T)



回答3:


Reduce(function(x, y) x + replace(y, is.na(y), 0), mylist)/
    Reduce(`+`, lapply(mylist, function(x) !is.na(x)))
#  x   y
#1 2 3.5
#2 3 4.0

OR

nm = c("x", "y")  # could do `nm = names(mylist[[1]])`
sapply(nm, function(NM)
    rowMeans(do.call(cbind, lapply(mylist, function(x) x[NM])), na.rm = TRUE))
#     x   y
#[1,] 2 3.5
#[2,] 3 4.0


来源:https://stackoverflow.com/questions/55229201/calculate-means-across-elements-in-a-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!