Home > Blockchain >  mean for replicate lists in R?
mean for replicate lists in R?

Time:08-24

I have simulation and data structures as follows (just a toy example):

foo = function(mu=0,lambda=1){
  x1 = rnorm(1,mu) #X~N(μ,1)
  y1 = rexp(1,lambda) #Y~Exp(λ)
  list(x=x1,y=y1)
}
mu = 1; lambda = 2 #true values: E(X)=μ=1; E(Y)=1/λ=0.5
set.seed(0); out = replicate(1000, foo(mu,lambda), simplify=FALSE)
# str(out)

Then we get a list out of length(out)=1000, with each list having out$x and out$y. I want to compute the means for 1000 out$xs and out$ys, respectively.

Of course, I can reach my goal through a not-clever way as

m = c() #for storing simulated values
for(i in 1:2){
  s = sapply( 1:1000, function(j)out[[j]][i] )
  m[i] = mean( as.numeric(s) )
}
m
# [1] 0.9736922 0.4999028

Can we use a more simple and efficient way to compute the means? I also try lapply(out, mean) and Reduce(" ",out)/1000, but failed...

CodePudding user response:

This is another option if the sublists are always the same length:

> rowMeans(matrix(unlist(out),2))
[1] 0.9736922 0.4999028

Or:

> rowMeans(replicate(1000,unlist(foo(mu,lambda))))
        x         y 
0.9736922 0.4999028 

CodePudding user response:

An option is to use purrr::transpose

library(purrr)
out %>% transpose() %>% map(~ mean(unlist(.x)[1:1000]))
# Or: out[1:1000] %>% transpose() %>% map(~ mean(unlist(.x)))
#$x
#[1] 0.9736922
#
#$y
#[1] 0.4999028

Or a base R solution using lapply (which is essentially the same as your explicit for loop):

lapply(c("x", "y"), function(var) mean(sapply(out[1:1000], "[[", var)))
#[[1]]
#[1] 0.9736922
#
#[[2]]
#[1] 0.4999028
  • Related