2015-10-21 4 views
3

J'essaie de calculer une somme roulante groupée basée sur une taille de fenêtre k mais, dans le cas où l'indice intérieur de rangée de groupe (n) est inférieur à k, je veux calculer la somme roulante utilisant la condition k = min (n, k).calculer la somme roulante basée sur l'indice de ligne dans R

Mon problème est similaire à cette question R dplyr rolling sum mais je cherche une solution qui fournit une valeur non NA pour chaque ligne.

Je peux obtenir une partie du chemin en utilisant dplyr et rollsum:

library(zoo) 
library(dplyr) 
df <- data.frame(Date=rep(seq(as.Date("2000-01-01"), 
      as.Date("2000-12-01"),by="month"),2), 
      ID=c(rep(1,12),rep(2,12)),value=1) 
df <- tbl_df(df) 
df <- df %>% 
     group_by(ID) %>% 
     mutate(total3mo=rollsum(x=value,k=3,align="right",fill="NA")) 

df 
Source: local data frame [24 x 4] 
Groups: ID [2] 

    Date ID value tota3mo 
    (date) (dbl) (dbl) (dbl) 
1 2000-01-01  1  1  NA 
2 2000-02-01  1  1  NA 
3 2000-03-01  1  1  3 
4 2000-04-01  1  1  3 
5 2000-05-01  1  1  3 
6 2000-06-01  1  1  3 
7 2000-07-01  1  1  3 
8 2000-08-01  1  1  3 
9 2000-09-01  1  1  3 
10 2000-10-01  1  1  3 
..  ... ... ...  ... 

Dans ce cas, ce que je voudrais revenir est la valeur 1 pour les observations sur 2000-01-01 et la valeur 2 pour observations le 2000-02-01. Plus généralement, j'aimerais que la somme roulante soit calculée sur la plus grande fenêtre possible mais pas plus grande que k.

Dans ce cas particulier, il n'est pas trop difficile de modifier certaines valeurs NA à la main. Cependant, en fin de compte je voudrais ajouter plusieurs colonnes à mon cadre de données qui seront des sommes de roulement calculées sur diverses fenêtres. Dans ce cas plus général, il sera assez fastidieux de revenir à la main changer de nombreuses valeurs NA.

Répondre

3

En utilisant l'argument partial=TRUE de rollapplyr:

df %>% 
    group_by(ID) %>% 
    mutate(roll = rollapplyr(value, 3, sum, partial = TRUE)) %>% 
    ungroup() 

ou sans dplyr (encore besoin zoo):

roll <- function(x) rollapplyr(x, 3, sum, partial = TRUE) 
transform(df, roll = ave(value, ID, FUN = roll))