Mean of vector inside of list of lists

匿名 (未验证) 提交于 2019-12-03 01:22:02

问题:

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?

回答1:

Another idea:

tmp = unlist(mylist, F) sapply(unique(names(tmp)),         function(x) colMeans(do.call(rbind, tmp[grep(x, names(tmp))]))) #       a   b #[1,] 3.5 5.5 #[2,] 4.5 6.5 #[3,] 5.5 7.5 


回答2:

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  


回答3:

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 


回答4:

Here's a data.table and RcppRoll combination (should be super fast for big lists)

library(data.table) library(RcppRoll) roll_mean(as.matrix(rbindlist(mylist)), 4, weights=c(1,0,0,1))  ##     [,1] [,2] ## [1,]  3.5  5.5 ## [2,]  4.5  6.5 ## [3,]  5.5  7.5 


回答5:

One of many possible approaches, via data.frame

mylist <- list(list(a = 1:3, b = 4:6),list(a = 6:8, b = 7:9))  sapply(c("a","b"),function(x){   listout <- lapply(mylist,"[[",x)   rowMeans(do.call(cbind,listout)) })         a   b [1,] 3.5 5.5 [2,] 4.5 6.5 [3,] 5.5 7.5 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!