Getting the mean of 2 variables across a list of lists in R

Viewed 119

After my replicate() call below, I was wondering how I could get the mean of 'Estimate' and 'Std. Error' for x1 and x2 across the list?

foo <- function(){
x1 <- rnorm(20) ; x2 <- rnorm(20,2); y <- rnorm(20,3)
coef(summary(lm(y~x1+x2)))[,1:2]  }

# Now replicate foo():

replicate(2, foo(), simplify = F) # How to get the mean of 'Estimate' and 'Std. Error' for 'x1' and 'x2' after loop

 ### OUTPUT:

[[1]]
              Estimate  Std. Error
(Intercept)  3.1356507  0.4874282
x1          -0.3408958  0.2033072
x2          -0.1335315  0.2513356

[[2]]
             Estimate Std. Error
(Intercept) 2.5574090  0.4354596
x1          0.0850336  0.3101341
x2          0.2348902  0.1754149
3 Answers

First, we fix the list so that we can see the results for different methods:

set.seed(111)
dat = replicate(2, foo(), simplify = F)

dat
[[1]]
               Estimate Std. Error
(Intercept)  3.47644151  0.4100162
x1          -0.04314488  0.2769444
x2          -0.04946731  0.1860911

[[2]]
               Estimate Std. Error
(Intercept)  2.96378594  0.5265807
x1           0.22268874  0.3517643
x2          -0.04437585  0.2468499

Using base R "Reduce" :

Reduce(`+`,dat)/length(dat)
               Estimate Std. Error
(Intercept)  3.22011373  0.4682984
x1           0.08977193  0.3143544
x2          -0.04692158  0.2164705

Using purrr:

library(purrr)
reduce(dat,`+`)/length(dat)

               Estimate Std. Error
(Intercept)  3.22011373  0.4682984
x1           0.08977193  0.3143544
x2          -0.04692158  0.2164705

A tidyverse solution could be

library(tidyverse)
replicate(2, foo(), simplify = FALSE) %>% #could use purrr::rerun here
  map_df(as_tibble, rownames = "coef") %>% 
  group_by(coef) %>% 
  summarise(across(.fns = mean))

  coef        Estimate `Std. Error`
  <chr>          <dbl>        <dbl>
1 (Intercept)    3.58         0.514
2 x1            -0.131        0.206
3 x2            -0.223        0.224

With base R, we can also convert to array and get the mean. It would also take care of NA elements if present

apply(array(unlist(dat), c(3, 2, 2)), 1:2, mean, na.rm = TRUE)
#          [,1]      [,2]
#[1,]  3.22011373 0.4682984
#[2,]  0.08977193 0.3143544
#[3,] -0.04692158 0.2164705

data

set.seed(111)
dat <- replicate(2, foo(), simplify = FALSE)
Related