首页 > 解决方案 > 如何计算数据框块的累积平均值,直到 R 中的每一行

问题描述

我有一个简化的数据框,如下所示:

df
volume ask1 ask2 bid1 bid2
0      38   NA   38   37.9
100    38.1 38.2 37.8 38.2
0      38.4 38.5 38.2 38.3
0      38.4 38.5 38.2 NA
200    38.3 38.1 38   38.4
250    38.4 38.2 NA   38.6

我想要另一列,其中包含第 th 行的df[1:i, 2:5]平均值i

我可以用 for 循环做到这一点:

df[, "midpoint"] <- NA
for (i in 1:nrow(df)) {
   df$midpoint[i] <- mean(as.matrix(df[c(1:i), c(2:5)]), na.rm = TRUE)
}

但是由于我的数据框实际上很大,所以 for 循环需要很长时间。

我试过sapply但失败了:

df[, "midpoint"] <- sapply(df, function(i) mean(as.matrix(df[c(1:i), c(2:5)]), na.rm = TRUE))

谁能给我一些建议?

标签: rdataframe

解决方案


有了sapply你可以做:

mat <- as.matrix(df[, 2:5])
df$midpoint <- sapply(seq(nrow(df)), function(i) mean(mat[1:i, ], na.rm = TRUE))

您也可以采用更快但会引入小错误的方法。

library(dplyr)
df %>%
  mutate(res = rowMeans(select(., 2:5), na.rm = TRUE), 
         res = cummean(res))

#  volume ask1 ask2 bid1 bid2 midpoint      res
#1      0 38.0   NA 38.0 37.9 37.96667 37.96667
#2    100 38.1 38.2 37.8 38.2 38.02857 38.02083
#3      0 38.4 38.5 38.2 38.3 38.14545 38.13056
#4      0 38.4 38.5 38.2   NA 38.19286 38.18958
#5    200 38.3 38.1 38.0 38.4 38.19444 38.19167
#6    250 38.4 38.2   NA 38.6 38.22381 38.22639

midpoint是 for 循环或sapply代码的实际答案,res也是上述计算的答案。


推荐阅读