calculating mean for every n values from a vector

被刻印的时光 ゝ 提交于 2019-11-26 16:56:57

问题


So lets say I have a vector

a <- rnorm(6000)

I want to calculate the mean of the 1st value to the 60th, then again calculate the mean for the 61st value to the 120th and so fourth. So basically I want to calculate the mean for every 60th values giving me 100 means from that vector. I know I can do a for loop but I'd like to know if there is a better way to do this?


回答1:


I would use

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

Enhancement on user adunaic's request

This only works if there are 60x100 data points. If you have an incomplete 60 at the end then this errors. It would be good to have a general solution for others looking at this problem for ideas.

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

Alternative solution with group-by operation (less efficient)

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

Speed

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



回答2:


Another option is to use tapply by creating a grouping variable.

Grouping variable could be created in two ways :

1) Using rep

tapply(a, rep(seq_along(a), each = n, length.out = length(a)), mean)

2) Using gl

tapply(a, gl(length(a)/n, n), mean)

If we convert the vector to dataframe/tibble we can use the same logic and calculate the mean

aggregate(a~gl(length(a)/n, n), data.frame(a), mean)

OR with dplyr

library(dplyr)

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

data

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



回答3:


I would recommend using the sapply function:

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


来源:https://stackoverflow.com/questions/43635846/calculating-mean-for-every-n-values-from-a-vector

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!