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

StackOverflow https://stackoverflow.com/questions/4422363

  •  09-10-2019
  •  | 
  •  

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

Était-ce utile?

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 Comparaison des lisses directe et lisse de MA

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top