【问题标题】:Calculate mean of a range of rows计算一系列行的平均值
【发布时间】:2023-03-27 18:57:01
【问题描述】:

给定这样的数据框:

A <- c(1,2,3,4,NA,6,7,8,9,10,11,12,13,14,15)
B <- c(NA,NA,NA,20,NA,NA,NA,15,NA,NA,NA,NA,11,NA,9)
DF <- data.frame(A, B)

我想根据 B 列中的值计算 A 列中一系列值的平均值。具体来说,每当 B 列中有一个非 NA 值时,我想计算A 列中第 2 行和第 2 行的范围。

比如B列第一个非NA值是20,所以我想计算上面两行(2, 3)、下面两行(NA, 6)和相邻行的均值(4)。所以:

mean(2,3,4,NA,6)

同样,B 行中的下一个非 NA 值是 15。这将是

mean(6,7,8,9,10)

因此,整个数据框的最终结果将是一个新列 C

DF$C <- c(NA,NA,NA,3.75,NA,NA,NA,8,NA,NA,NA,NA,13,NA,14)

【问题讨论】:

    标签: r dataframe mean


    【解决方案1】:

    这是zoo 包的一种方法:

    library(zoo)
    width <- 5   # the observation ± 2
    
    DF$C <- rollapply(DF$A, width, mean, na.rm = TRUE, partial = TRUE)
    
    # when DF$B is NA, assign NA to corresponding DF$C
    DF$C[is.na(DF$B)] <- NA
    

    partial = TRUE 允许在无法容纳整个窗口的 DF$A 向量的前导和尾随部分计算平均值(即 DF$A 的前 2 个和后 2 个值,其中大小为 5 的窗口是不可能的)。

    【讨论】:

      【解决方案2】:

      您可以尝试以下方法。

      nona <- !is.na(DF$B)
      DF$C <- replace(
          DF$B, 
          nona, 
          vapply(which(nona), function(i) {
              ii <- (i-2):(i+2)
              mean(DF$A[ii[ii > 0]], na.rm = TRUE)
          }, 1)
      )
      

      在这里,我们在 B 列中找到非 NA 值,然后使用该向量为我们想要在 A 列中找到平均值的值设置索引,小心删除可能出现的任何负下标应该B列的前一个或两个值不是NA。上面的代码给出了DF的以下结果。

          A  B     C
      1   1 NA    NA
      2   2 NA    NA
      3   3 NA    NA
      4   4 20  3.75
      5  NA NA    NA
      6   6 NA    NA
      7   7 NA    NA
      8   8 15  8.00
      9   9 NA    NA
      10 10 NA    NA
      11 11 NA    NA
      12 12 NA    NA
      13 13 11 13.00
      14 14 NA    NA
      15 15  9 14.00
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-03
        • 2023-01-27
        • 1970-01-01
        • 2016-09-02
        • 1970-01-01
        • 2016-10-13
        • 1970-01-01
        • 2011-05-17
        相关资源
        最近更新 更多