I'm working with panel data. I want to add 3 and 5-year moving averages of some of my variables into my dataset. I have the following code which works fine but is very long. Is there a neater and more efficient way of creating moving averaged variables?
dataset <- dataset %>%
group_by(iso3c) %>%
dplyr::mutate(manu_GDP_3=rollapply(manu_GDP,3,mean,align='right',fill=NA),
manu_GDP_5=rollapply(manu_GDP,5,mean,align='right',fill=NA),
age_dep_3=rollapply(age_dep,3,mean,align='right',fill=NA),
age_dep_5=rollapply(age_dep,5,mean,align='right',fill=NA),
agr_GDP_3=rollapply(agr_GDP,3,mean,align='right',fill=NA),
agr_GDP_5=rollapply(agr_GDP,5,mean,align='right',fill=NA),
services_GDP_3=rollapply(services_GDP,3,mean,align='right',fill=NA),
services_GDP_5=rollapply(services_GDP,5,mean,align='right',fill=NA),
debtGNI_3=rollapply(debtGNI,3,mean,align='right',fill=NA),
debtGNI_5=rollapply(debtGNI,5,mean,align='right',fill=NA),
Foreign_liab_3=rollapply(Foreign_liab,3,mean,align='right',fill=NA),
Foreign_liab_5=rollapply(Foreign_liab,5,mean,align='right',fill=NA),
intcapimp_X_3=rollapply(intcapimp_X,3,mean,align='right',fill=NA),
intcapimp_X_5=rollapply(intcapimp_X,5,mean,align='right',fill=NA),
regime_3=rollapply(regime,3,mean,align='right',fill=NA),
regime_5=rollapply(regime,5,mean,align='right',fill=NA),
CBI2_3=rollapply(CBI2,3,mean,align='right',fill=NA),
CBI2_5=rollapply(CBI2,5,mean,align='right',fill=NA),
resource_rent_3=rollapply(resource_rent,3,mean,align='right',fill=NA),
resource_rent_5=rollapply(resource_rent,5,mean,align='right',fill=NA),
oil_rents_3=rollapply(oil_rents,3,mean,align='right',fill=NA),
oil_rents_5=rollapply(oil_rents,5,mean,align='right',fill=NA),
coal_rents_3=rollapply(coal_rents,3,mean,align='right',fill=NA),
coal_rents_5=rollapply(coal_rents,5,mean,align='right',fill=NA)) %>%
ungroup()
A couple things:
zoo::rollmean
(and its*r
right variant) are more efficient thanrollapply(., n, mean)
, I suggest using it instead. (Edit: G. Grothendieck said thatzoo::rollapply*
will userollmean
when able, perhaps my comment here is outdated or misled.)across
allows you to iterate one or more functions over a selection of columns. I'm usingacross(Sepal.Length:Petal.Width
, ..)below, but it could easily be
across(c(Sepal.Length, Petal.Width, Sepal.Width), ..)` just as easily. When given a list of functions, the naming convention seems intuitive, see the results below.This means your code might be reduced to the following (untested):