R:计算来自矢量的每n个值的平均值

are*_*aie 4 r vector mean

所以我要说我有一个向量

a <- rnorm(6000)
Run Code Online (Sandbox Code Playgroud)

我想计算第一个值到60的平均值,然后再次计算第61个值到第120个的平均值,然后是第四个.所以基本上我想计算每60个值的平均值,从该向量给出100个均值.我知道我可以做一个for循环,但我想知道是否有更好的方法来做到这一点?

李哲源*_*李哲源 11

我会用

 colMeans(matrix(a, 60))
.colMeans(a, 60, length(a) / 60)  # more efficient (without reshaping to matrix)
Run Code Online (Sandbox Code Playgroud)

增强用户adunaic的要求

仅当有60x100个数据点时才有效.如果你最后有一个不完整的60,那么这个错误.为其他人提供一个通用的解决方案可以很好地解决这个问题.

BinMean <- function (vec, every, na.rm = FALSE) {
  n <- length(vec)
  x <- .colMeans(vec, every, n %/% every, na.rm)
  r <- n %% every
  if (r) x <- c(x, mean.default(vec[(n - r + 1):n], na.rm = na.rm))
  x
  }

a <- 1:103
BinMean(a, every = 10)
# [1]   5.5  15.5  25.5  35.5  45.5  55.5  65.5  75.5  85.5  95.5 102.0
Run Code Online (Sandbox Code Playgroud)

采用分组操作的替代解决方案(效率较低)

BinMean2 <- function (vec, every, na.rm = FALSE) {
  grp <- as.integer(ceiling(seq_along(vec) / every))
  grp <- structure(grp, class = "factor",
                   levels = as.character(seq_len(grp[length(grp)])) )
  lst <- .Internal(split(vec, grp))
  unlist(lapply(lst, mean.default, na.rm = na.rm), use.names = FALSE)
  }
Run Code Online (Sandbox Code Playgroud)

速度

library(microbenchmark)
a <- runif(1e+4)
microbenchmark(BinMean(a, 100), BinMean2(a, 100))
#Unit: microseconds
#             expr      min        lq       mean    median        uq       max
#  BinMean(a, 100)   40.400   42.1095   54.21286   48.3915   57.6555   205.702
# BinMean2(a, 100) 1216.823 1335.7920 1758.90267 1434.9090 1563.1535 21467.542
Run Code Online (Sandbox Code Playgroud)