我有一个列表清单,其中包含以下结构:
> 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
我想在a
的向量b
和mylist
之间得到元素方面的平均值。对于向量a
,结果将是:
> a
[1] 3.5 4.5 5.5
我知道函数lapply
,rbind
和colMeans
,但我无法用它们来解决问题。我怎样才能达到我的需要?
答案 0 :(得分:6)
以下是一种使用“reshape2”中的melt
和dcast
的方法。
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
以下是基础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
答案 1 :(得分:4)
已更新:更好...... sapply(mylist, unlist)
实际上为我们提供了一个很好的矩阵来应用rowMeans
。
> rowMeans(sapply(mylist, unlist))
# a1 a2 a3 b1 b2 b3
# 3.5 4.5 5.5 5.5 6.5 7.5
原文:
另一个lapply
方法,其中抛出sapply
。
> 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
答案 2 :(得分:2)
另一个想法:
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
答案 3 :(得分:2)
这里有一个data.table
和RcppRoll
组合(对于大型列表应该超级快)
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
答案 4 :(得分:1)
许多可能的方法之一,通过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