【问题标题】:for loop in R to calculate mean from listR中的for循环从列表中计算平均值
【发布时间】:2017-07-15 08:54:21
【问题描述】:

这个post 也经过了交叉验证,我被指示在这里发帖。

我有一个名为 d 的列表,其中包含 R 中的值。

> 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 

        }

如何使这个循环自动执行?谢谢。

【问题讨论】:

    标签: r for-loop mean


    【解决方案1】:

    正如@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 来计算平均值。

    【讨论】:

    • 这是一个不错的解决方案,+1。
    【解决方案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
    

    基本上,您只需将mean(as.numeric(lapply(d,"[",n=j))) 插入到您的for 循环中。

    【讨论】:

    • 你提出了一个嵌套循环,对我来说似乎有点矫枉过正。
    • @Val 我同意,您的建议在数值上更有效。我只是想提供一个替代方案,以防有人想在for 循环中执行此操作(无论出于何种原因)。
    猜你喜欢
    • 2021-02-02
    • 1970-01-01
    • 2016-12-22
    • 2022-01-05
    • 1970-01-01
    • 2021-10-02
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多