从向量中计算每n个值的平均值

7
所以假设我有一个向量。
a <- rnorm(6000)

我希望计算第一个值到第60个值的平均值,然后再计算第61个值到第120个值的平均值,以此类推。因此,我想为每60个值计算一次平均值,从而得到该向量的100个平均值。我知道我可以使用for循环来实现,但我想知道是否有更好的方法来完成这个任务?


你可能会很高兴看一下apply()函数。 - Trolldejo
1
应用函数大多适用于数据框和矩阵。我在这里询问的是一个向量。 - arezaie
3个回答

16

我会使用

 colMeans(matrix(a, 60))
.colMeans(a, 60, length(a) / 60)  # more efficient (without reshaping to matrix)

根据用户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

通过分组操作实现的另一种解决方案(效率较低)

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)
  }

速度

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

4

我推荐使用sapply

a <- rnorm(6000)
seq <- seq(1, length(a), 60)
a_mean <- sapply(seq, function(i) {mean(a[i:(i+59)])})

1
另一个选项是使用tapply通过创建分组变量来实现。
可以通过两种方式创建分组变量: 1)使用rep
tapply(a, rep(seq_along(a), each = n, length.out = length(a)), mean)

2) 使用 gl
tapply(a, gl(length(a)/n, n), mean)

如果我们将向量转换为数据框/表,我们可以使用相同的逻辑计算平均值。
aggregate(a~gl(length(a)/n, n), data.frame(a), mean)

使用 dplyr 进行或运算。
library(dplyr)

tibble::tibble(a) %>%
          group_by(group = gl(length(a)/n, n)) %>%
          summarise(mean_val = mean(a))

数据

set.seed(1234)
a <- rnorm(6000)
n <- 60

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