使用R中的for循环计算列表的平均值

4
这个帖子也在交叉验证网站上发布过,我被引导到这里发帖。
我有一个在R中包含值的名为d的列表。
> d
$`2017-07-15:10:09:22`
[1] 3.125 4.375 2.500 0.625 5.000 3.750 1.875 1.250

$`2017-07-15:10:10:04`
[1] 0.625 3.750 3.125 1.875 1.250 4.375 2.500 5.000

$`2017-07-15:11:45:45`
[1] 4.375 3.125 3.750 2.500 5.000 1.875 1.250 0.625

我想计算这些点的平均值并保存到数据框中。因此,我使用for循环来完成这个任务。

l2 <- length(d)
for(j in 1:6)
{
      df$Mean[j] <- (d[[1]][j] 
            + d[[2]][j] + d[[3]][j])/l2 

}

每次列表 d 的长度都会变得更长。我希望让这个 for 循环自己计算平均值,就像这样。

l2 <- length(d)   
for(j in 1:6)
       {
              df$Mean[j] <- (d[[1]][j] 
                    + d[[2]][j] + d[[3]][j] + d[[4]][j] + ....
               )/l2 

        }

如何使这个循环自动运行?谢谢。
2个回答

4
正如@F.Maas所正确指出的那样,在这里您不需要循环。
但如果我正确理解了您的问题,您想要每个点在所有列表元素上的平均值,而不是每个列表元素内点的平均值。
如果我的假设是正确的,那么这段代码应该能满足您的需求,甚至不需要使用lapply:
#create test data and names
d <- lapply(1:3,function(x) runif(6))
names(d) <- sample(LETTERS,length(d))

> d
$V
[1] 0.9369505 0.7825348 0.4549225 0.3807600 0.7169146 0.3608166

$Z
[1] 0.75466094 0.09207062 0.59738221 0.33558258 0.79022386 0.98266940

$G
[1] 0.3441581 0.6696056 0.5544217 0.7422718 0.6682706 0.7989314


#calculate means

res <- colMeans(do.call(rbind,d))

现在你已经有了每个点的手段。您可以将它们添加到现有的data.frame中或创建一个新的。
#put into df

df <- data.frame(means=res)

#output

> df
      means
1 0.6785898
2 0.5147370
3 0.5355755
4 0.4862048
5 0.7251363
6 0.7141391

因此,您唯一需要的是colMeans(do.call(rbind,d)),它将您的列表合并为一个矩阵,每列代表一个点。之后,我只需使用colMeans计算平均值。


2
我认为这就是你正在寻找的(示例代码):

> set.seed(1)
> data<-list(a=rnorm(10),b=rnorm(10),c=rnorm(10),d=rnorm(10))
> data_mean<-rep(0,10)
> data
$a
 [1] -0.6264538  0.1836433 -0.8356286  1.5952808  0.3295078 -0.8204684  0.4874291  0.7383247  0.5757814
[10] -0.3053884

$b
 [1]  1.51178117  0.38984324 -0.62124058 -2.21469989  1.12493092 -0.04493361 -0.01619026  0.94383621
 [9]  0.82122120  0.59390132

$c
 [1]  0.91897737  0.78213630  0.07456498 -1.98935170  0.61982575 -0.05612874 -0.15579551 -1.47075238
 [9] -0.47815006  0.41794156

$d
 [1]  1.35867955 -0.10278773  0.38767161 -0.05380504 -1.37705956 -0.41499456 -0.39428995 -0.05931340
 [9]  1.10002537  0.76317575

> lapply(data,"[",n=4) #access the 4th entry of every list part - only needs to be transformed to numeric vector
$a
[1] 1.595281

$b
[1] -2.2147

$c
[1] -1.989352

$d
[1] -0.05380504

> for(i in 1:length(data[[1]]))(
+   data_mean[i]<-mean(as.numeric(lapply(data,"[",n=i)))
+ )
> data_mean
 [1]  0.79074607  0.31320878 -0.24865815 -0.66564396  0.17430122 -0.33413132 -0.01971167  0.03802378
 [9]  0.50471947  0.36740756

基本上,你只需要在你的for循环中插入mean(as.numeric(lapply(d,"[",n=j)))

你提出了嵌套循环,对我来说似乎有些杀鸡焉用牛刀了。 - Val
@Val 我同意你的建议更加数字高效。我只是想提供一个替代方案,以防有人想用 for 循环来实现这个功能(无论出于什么原因)。 - Eldioo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接