Est-il possible de forcer zoo :: fonction rollmean retourner un vecteur qui est la même longueur que l'entrée de ce? (Ou peut-être utiliser une autre fonction?)
Question
input = cbind(c(3,7,3,5,2,9,1,4,6,4,7,3,7,4))
library(zoo)
output = cbind(rollmean(input,4))
print(input)
print(output)
sortie:
[,1]
[1,] 3
[2,] 7
[3,] 3
[4,] 5
[5,] 2
[6,] 9
[7,] 1
[8,] 4
[9,] 6
[10,] 4
[11,] 7
[12,] 3
[13,] 7
[14,] 4
[,1]
[1,] 4.50
[2,] 4.25
[3,] 4.75
[4,] 4.25
[5,] 4.00
[6,] 5.00
[7,] 3.75
[8,] 5.25
[9,] 5.00
[10,] 5.25
[11,] 5.25
mais lorsque je tente de cbind il:
Error in cbind(input, output) :
number of rows of matrices must match (see arg 2)
Calls: print -> cbind
Execution halted
Je voudrais utiliser une fonction qui serait assez intelligent et ne donnent pas si elle ne reçoit pas de données sur les deux extrémités d'un vecteur et calcul de la production alors selon que les données qu'il est d'avoir. Ainsi, par exemple en entrée [1] il calculera seul moyen de droite
La solution
Regardez l'argument na.pad
à rollmean()
, et le mettre à TRUE
. Vous avez manqué le dernier bit; Vous devez donc également d'aligner les moyens à droite:
> input <- c(3,7,3,5,2,9,1,4,6,4,7,3,7,4)
> rollmean(input, 4, na.pad = TRUE, align = "right")
[1] NA NA NA 4.50 4.25 4.75 4.25 4.00 5.00 3.75 5.25 5.00 5.25 5.25
Sauf si vous avez besoin de ces choses comme matrices 1 colonnes, déposez les appels cbind()
.
OK, de précisions supplémentaires il semble que vous voulez calculer des moyens qui ne sont pas vraiment comparables aux autres moyens dans le vecteur de résultat. Mais si vous devez ...
> k <- 4
> c( cumsum(input[1:(k-1)]) / 1:(k-1), rollmean(input, k, align = "right") )
[1] 3.000000 5.000000 4.333333 4.500000 4.250000 4.750000 4.250000 4.000000
[9] 5.000000 3.750000 5.250000 5.000000 5.250000 5.250000
Comme l'OP est intéressé par l'estimation de la MA pour ensuite adapter à une spline, il pourrait être intéressant de voir ce que l'on gagne en faisant cela au lieu d'estimer la spline directement à partir des données.
> ## model observed data
> mod <- smooth.spline(seq_along(input), input, df = 3)
> ## plot data and fitted spline
> plot(seq_along(input), input)
> lines(predict(mod, seq_along(input)), col = "red", lwd = 2)
> ## model the fudged MA
> mod2 <- smooth.spline(seq_along(input),
+ c( cumsum(input[1:(k-1)]) / 1:(k-1),
+ rollmean(input, k, align = "right") ), df = 3)
> ## add this estimated spline
> lines(predict(mod2, seq_along(input)), col = "blue", lwd = 2)
Vous auriez beaucoup poussé à faire la différence entre ces deux
et les courbes dévient plus au début où vous obligez estimation de la MA.
Autres conseils
Bien que ce soit une vieille question, pour toute personne lisant cela, elle pourra être utile.
Utilisation rollapply avec une moyenne de fonction, et partielle = TRUE gardera les valeurs initiales où la fonction ne peut être calculé.
x <- rollapply(input, width = 5, FUN = mean, align = "centre", partial = TRUE")
??rollapply
??rollapplyr # for right aligned moving average
Vous serait vraiment profiter de la lecture de la documentation. Voir ?rollmean
, en particulier les arguments de na.pad
et align
.
Jusqu'à présent, la question a été considérée comme ambiguë par trois expérience codeurs R, mais il semble que vous ne voulez une sorte de valeur extrapolée pour les moyens manquants. Que vous vouliez les valeurs imputées au début ou à la fin ne sait pas. Ce code renvoie un vecteur aligné à droite et remplacer le début NA est la première valeur non-NA. Il y aurait également la fonction na.locf dans le zoo si vous voulez travailler avec rollmeans aligné à gauche.
long.roll <- function(input, k) { rtroll <-
rollmean(input, k, align="right", na.pad=TRUE)
return(c(rep(rtroll[k], k-1), rtroll[-(1:(k-1))]) ) }
long.roll(input,4)
# [1] 4.50 4.50 4.50 4.50 4.25 4.75 4.25 4.00 5.00 3.75 5.25 5.00 5.25
# [14] 5.25