Здесь возможен data.table
подход:
#calculate the 5-yearly percentage changes first by
#i) first creating all combinations of ID and 5-yearly years
#2) then join with the original dataset
#3) then leading the Population column and calculating Growth
pctChange <- dt[CJ(ID=ID, year=seq(1967, 2022, 5), unique=TRUE),
.(ID, year, Growth=(shift(Population, type="lead") - Population) / Population),
on=.(ID, year)]
#then perform a rolling join (`roll=TRUE`; see ?data.table) and
#then update the original dt with Growth by reference (i.e. `:=`)
dt[, Growth := pctChange[dt, Growth, on=.(ID, year), roll=TRUE]]
dt
вывод:
ID Population year Growth
1: 1 50 1995 NA
2: 1 60 1996 NA
3: 1 70 1997 0.5714286
4: 1 80 1998 0.5714286
5: 1 90 1999 0.5714286
6: 1 100 2000 0.5714286
7: 1 105 2001 0.5714286
8: 1 110 2002 0.8181818
9: 1 120 2003 0.8181818
10: 1 130 2004 0.8181818
11: 1 140 2005 0.8181818
12: 1 150 2006 0.8181818
13: 1 200 2007 NA
14: 1 300 2008 NA
Обратите внимание: скользящее соединение не работает с обновлением соединения
dt[pctChange, Growth := Growth, on=.(ID, year), roll=TRUE]