2013-07-10 12 views
5

Sospetto che questa sia una domanda piuttosto semplice con più soluzioni, ma sono ancora un po 'novizio in R e una ricerca esaustiva non ha prodotto risposte che parlassero bene a quello che ho m che voglio fare.Generazione di una variabile somma mobile in R

Sto cercando di creare, per mancanza di un termine migliore, "spostare somme" per una variabile nel mio frame di dati. Si tratterebbe di somme di 3 anni e di 5 anni, in ritardo di un anno. Quindi, una somma di 5 anni per un'osservazione nel 1986 sarebbe la somma di tutte le precedenti osservazioni nel 1981, 1982, 1983, 1984 e 1985. Ecco un esempio di ciò che vorrei fare, dove la variabile somma è la somma di tutti x nei cinque anni precedenti l'anno di osservazione.

country  year  x  x5yrsum 
    A   1980  9  NA 
    A   1981  3  NA 
    A   1982  5  NA 
    A   1983  6  NA 
    A   1984  9  NA 
    A   1985  7  32 
    A   1986  9  30 
    A   1987  4  36 

    ..................... 

    B   1990  0  NA 
    B   1991  4  NA 
    B   1992  2  NA 
    B   1993  6  NA 
    B   1994  3  NA 
    B   1995  7  15 
    B   1996  0  22 

Dati di pannello non bilanciati. Sospetto che lo ddply sia appropriato, ma non saprei la codifica esatta per esso.

Qualsiasi input sarebbe apprezzato.

+0

Dai un'occhiata a '? Rollsum' dal pacchetto' zoo'. Combinato con 'aggregate',' data.table' o 'ddply' dovresti essere impostato. – Justin

risposta

7

È possibile utilizzare filter in ddply (o qualsiasi altra funzione che implementa il metodo "split-applica-combinazione"):

library(plyr) 
ddply(DF, .(country), transform, 
      x5yrsum2 = as.numeric(filter(x,c(0,rep(1,5)),sides=1))) 

# country year x x5yrsum x5yrsum2 
# 1  A 1980 9  NA  NA 
# 2  A 1981 3  NA  NA 
# 3  A 1982 5  NA  NA 
# 4  A 1983 6  NA  NA 
# 5  A 1984 9  NA  NA 
# 6  A 1985 7  32  32 
# 7  A 1986 9  30  30 
# 8  A 1987 4  36  36 
# 9  B 1990 0  NA  NA 
# 10  B 1991 4  NA  NA 
# 11  B 1992 2  NA  NA 
# 12  B 1993 6  NA  NA 
# 13  B 1994 3  NA  NA 
# 14  B 1995 7  15  15 
# 15  B 1996 0  22  22 
3

Se DF è il frame di dati a tre colonne ingresso quindi utilizzare ave con rollapplyr da zoo. Si noti che usiamo larghezza k+1 e poi cadere il k + 1 ° elemento dalla somma in modo che il valore corrente di x viene escluso e solo il restante k valori vengono sommati:

library(zoo) 

k <- 5 
roll <- function(x) rollapplyr(x, k+1, function(x) sum(x[-k-1]), fill = NA) 
transform(DF, xSyrsum = ave(x, country, FUN = roll)) 

che dà:

country year x xSyrsum 
1  A 1980 9  NA 
2  A 1981 3  NA 
3  A 1982 5  NA 
4  A 1983 6  NA 
5  A 1984 9  NA 
6  A 1985 7  32 
7  A 1986 9  30 
8  A 1987 4  36 
9  B 1990 0  NA 
10  B 1991 4  NA 
11  B 1992 2  NA 
12  B 1993 6  NA 
13  B 1994 3  NA 
14  B 1995 7  15 
15  B 1996 0  22 
Problemi correlati