3

The dataset

firstList  <- list(a = 1:3, b = 4:6)
secondList <- list(c = 7:9, d = 10:12)

I am trying to calculate the mean of multiple lists with mapply.

mapply(mean, firstList, secondList)

It did not work because mean only averages its first argument as per Using mapply with mean function on a matrix

This works correctly:

mapply(mean, firstList)
mapply(mean, secondList)

I then tried lapply to supply one list at a time to mapply

lapply(c(firstList, secondList), function(x) mapply(mean, x))

The output was NOT the mean but the individual lists

What I need is how to calculate the mean of multiple list using mapply. I also would appreciate an explanation as of why mapply did not return the lists `mean'

Many thanks in advance

Community
  • 1
  • 1
Ragy Isaac
  • 1,458
  • 1
  • 17
  • 22

1 Answers1

3

According to ?mean, the usage is

mean(x, ...)

In the mapply, we have 'x' and 'y', so we can concatenate the corresponding list elements to make a single 'x' and then take the mean

mapply(function(x,y) mean(c(x,y)), firstList, secondList)
#a b 
#5 8 

same as,

mean(c(1:3, 7:9))
#[1] 5

If we are using a combination of apply functions, we can concatenate with Map, and then loop the list elements with sapply to get the mean

sapply(Map(c, firstList, secondList), mean)
# a b 
#5 8 

Or if the lengths of list elements are the same, we can use colMeans as the mapply/c output is a matrix without SIMPLIFY=FALSE

colMeans(mapply(c, firstList, secondList)) 
#a b 
#5 8 
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Thank you so much, you are saying that the number of parameters for the function must equal to the number of lists to be averaged, correct? – Ragy Isaac Sep 19 '15 at 09:45
  • 1
    @RagyIsaac It's related to the arguments in `mean`, which can take only `x`, where as with `mapply/Map`, you have x, y,... depending on the number of lists. Also, if there are many lists, instead of specifying `function(x,y,z, u)...`, you can just use `c` to concatenate all the corresponding list elements and then get the `mean` with `sapply` or use `colMeans` if the lengths are the same. – akrun Sep 19 '15 at 09:46
  • 1
    @RagyIsaac Another option is `library(data.table); rbindlist(list(firstList, secondList))[, lapply(.SD, mean)]` – akrun Sep 19 '15 at 09:50
  • Why lapply(c(firstList, secondList), function(x) mapply(mean, x)) did not work? – Ragy Isaac Sep 19 '15 at 10:02
  • 1
    @RagyIsaac If you look at the output of `c(firstList, secondList)`, it is a list of length 4. `lapply` will loop through the list elements. Each list element is a vector. Applying `mapply` on that vector, is like looping again each single vector element, and doing the `mean` is just doing the `mean` of a single value. – akrun Sep 19 '15 at 10:06
  • 1
    @RagyIsaac If you want the mean of each list element after the concatenation, `lapply(c(firstList, secondList), function(x) mapply(mean, list(x)))` or just `lapply(c(firstList, secondList), mean)` – akrun Sep 19 '15 at 10:07