Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mean of vector inside of list of lists

Tags:

list

r

mean

I have a list of lists with the following structure:

> mylist <- list(list(a=as.numeric(1:3), b=as.numeric(4:6)), 
                 list(a=as.numeric(6:8), b=as.numeric(7:9)))
> str(mylist)
List of 2
 $ :List of 2
  ..$ a: num [1:3] 1 2 3
  ..$ b: num [1:3] 4 5 6
 $ :List of 2
  ..$ a: num [1:3] 6 7 8
  ..$ b: num [1:3] 7 8 9

I would like to get the element-wise mean between the vectors a and b of mylist. For the vector a, the result would be this:

> a
[1] 3.5 4.5 5.5

I know the functions lapply, rbind and colMeans but I can't solve the problem with them. How can I achieve what I need?

like image 820
Jonas Schmedtmann Avatar asked Dec 06 '22 01:12

Jonas Schmedtmann


2 Answers

Here's one approach that uses melt and dcast from "reshape2".

library(reshape2)

## "melt" your `list` into a long `data.frame`
x <- melt(mylist)

## add a "time" variable to let things line up correctly
## L1 and L2 are created by `melt`
## L1 tells us the list position (1 or 2)
## L2 us the sub-list position (or name)
x$time <- with(x, ave(rep(1, nrow(x)), L1, L2, FUN = seq_along))

## calculate whatever aggregation you feel in the mood for
dcast(x, L2 ~ time, value.var="value", fun.aggregate=mean)
#   L2   1   2   3
# 1  a 3.5 4.5 5.5
# 2  b 5.5 6.5 7.5

Here's an approach in base R:

x <- unlist(mylist)
c(by(x, names(x), mean))
#  a1  a2  a3  b1  b2  b3 
# 3.5 4.5 5.5 5.5 6.5 7.5 
like image 174
A5C1D2H2I1M1N2O1R2T1 Avatar answered Dec 23 '22 16:12

A5C1D2H2I1M1N2O1R2T1


Updated : Better yet...sapply(mylist, unlist) actually gives us a nice matrix to apply rowMeans over.

> rowMeans(sapply(mylist, unlist))
#  a1  a2  a3  b1  b2  b3 
# 3.5 4.5 5.5 5.5 6.5 7.5 

Original : Another lapply method, with an sapply thrown in there.

> lapply(1:2, function(i) rowMeans(sapply(mylist, "[[", i)) )
# [[1]]
# [1] 3.5 4.5 5.5
#
# [[2]]
# [1] 5.5 6.5 7.5
like image 45
Rich Scriven Avatar answered Dec 23 '22 15:12

Rich Scriven