Alors disons que j'ai un vecteur
a <- rnorm(6000)
Je veux calculer la moyenne de la 1ère valeur à la 60e, puis à nouveau calculer la moyenne de la 61e valeur à la 120e et donc à la quatrième. Donc, fondamentalement, je veux calculer la moyenne pour toutes les 60 valeurs en me donnant 100 moyennes à partir de ce vecteur. Je sais que je peux faire une boucle for mais j'aimerais savoir s'il existe une meilleure façon de le faire
3 réponses
J'utiliserais
colMeans(matrix(a, 60))
.colMeans(a, 60, length(a) / 60) # more efficient (without reshaping to matrix)
Amélioration à la demande de l'utilisateur adunaic
Cela ne fonctionne que s'il y a 60x100 points de données. Si vous avez un 60 incomplet à la fin, ces erreurs. Il serait bon d'avoir une solution générale pour les autres qui cherchent des idées sur ce problème.
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
Solution alternative avec opération groupée (moins efficace)
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)
}
Vitesse
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
Une autre option consiste à utiliser tapply
en créant une variable de regroupement.
La variable de regroupement peut être créée de deux manières:
1) Utilisation de rep
tapply(a, rep(seq_along(a), each = n, length.out = length(a)), mean)
2) Utilisation de gl
tapply(a, gl(length(a)/n, n), mean)
Si nous convertissons le vecteur en dataframe / tibble, nous pouvons utiliser la même logique et calculer le mean
aggregate(a~gl(length(a)/n, n), data.frame(a), mean)
OU avec dplyr
library(dplyr)
tibble::tibble(a) %>%
group_by(group = gl(length(a)/n, n)) %>%
summarise(mean_val = mean(a))
données
set.seed(1234)
a <- rnorm(6000)
n <- 60
Je recommanderais d'utiliser la fonction sapply:
a <- rnorm(6000)
seq <- seq(1, length(a), 60)
a_mean <- sapply(seq, function(i) {mean(a[i:(i+59)])})
De nouvelles questions
r
R est un langage de programmation et un environnement logiciel libres et open source pour le calcul statistique, la bioinformatique, la visualisation et le calcul général. Veuillez fournir des exemples minimaux et reproductibles ainsi que le résultat souhaité. Utilisez dput () pour les données et spécifiez tous les packages non basiques avec des appels à library (). N'incorporez pas d'images pour les données ou le code, utilisez plutôt des blocs de code en retrait. Pour les questions relatives aux statistiques, utilisez https://stats.stackexchange.com.