24

I know this topic appeared on SO a few times, but the examples were often more complicated and I would like to have an answer (or set of possible solutions) to this simple situation. I am still wrapping my head around R and programming in general. So here I want to use lapply function or a simple loop to data list which is a list of three lists of vectors.

data1 <- list(rnorm(100),rnorm(100),rnorm(100))
data2 <- list(rnorm(100),rnorm(100),rnorm(100))
data3 <- list(rnorm(100),rnorm(100),rnorm(100))

data <- list(data1,data2,data3)

Now, I want to obtain the list of means for each vector. The result would be a list of three elements (lists).

I only know how to obtain list of outcomes for a list of vectors and

for (i in 1:length(data1)){
        means <- lapply(data1,mean)
}

or by:

lapply(data1,mean)

and I know how to get all the means using rapply:

rapply(data,mean)

The problem is that rapply does not maintain the list structure. Help and possibly some tips/explanations would be much appreciated.

MIH
  • 1,083
  • 3
  • 14
  • 26

1 Answers1

64

We can loop through the list of list with a nested lapply/sapply

 lapply(data, sapply, mean)

It is otherwise written as

 lapply(data, function(x) sapply(x, mean))

Or if you need the output with the list structure, a nested lapply can be used

 lapply(data, lapply, mean)

Or with rapply, we can use the argument how to get what kind of output we want.

  rapply(data, mean, how='list')

If we are using a for loop, we may need to create an object to store the results.

  res <- vector('list', length(data))
  for(i in seq_along(data)){
    for(j in seq_along(data[[i]])){
      res[[i]][[j]] <- mean(data[[i]][[j]])
    }
   }
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    wow, this is great (and somehow completely unintuitive to me, as i learned traditional loops first). just to grasp the idea, would you mind showing how it would look like in traditional for loop? that would help me to get idea about the indexing structure in case i need to apply some more complicated functions – MIH Jul 22 '15 at 11:07
  • why do you use `seq_along` instead of for instance `length` ? does it matter? – MIH Jul 22 '15 at 11:18
  • 4
    @Anna It is by practise. I think `1:length` can fail in some cases. For example, `l1 <- list();1:length(l1)# [1] 1 0; seq_along(l1)# integer(0)` – akrun Jul 22 '15 at 11:19
  • 2
    @akrun i know this is 5 years old but i this is so helpful i had to thank you anyway! – D.J Sep 01 '20 at 10:18
  • 1
    amazing. just amazing. many thx. – user2550228 Feb 23 '22 at 08:15