首页 > 解决方案 > 最近年份之间的百分比变化

问题描述

我在创建一个新变量时遇到问题,它等于以“2”和“7”结尾的最近年份之间 Growth的百分比变化。Population

# dt
ID       Population      year
1                50      1995
1                60      1996
1                70      1997
1                80      1998
1                90      1999
1               100      2000
1               105      2001
1               110      2002
1               120      2003
1               130      2004
1               140      2005
1               150      2006
1               200      2007
1               300      2008

dt <- data.table::fread("ID       Population      year
1                50      1995
  1                60      1996
  1                70      1997
  1                80      1998
  1                90      1999
  1               100      2000
  1               105      2001
  1               110      2002
  1               120      2003
  1               130      2004
  1               140      2005
  1               150      2006
  1               200      2007
  1               300      2008", header = T)

增长 = 以“2”和“7”结尾的最近年份之间流行的百分比变化。例如,在年份:
1996:(1997 流行 - 1992 流行)/ 1992 流行
1997:(2002 流行 - 1997 流行)/ 1997 流行
1998:(2002 流行 - 1997 流行)/ 1997 流行
1999:(2002 流行 - 1997流行)/1997 流行
2000:(2002 流行 – 1997 流行)/1997 流行
2001:(2002 流行 – 1997 流行)/1997 流行
2002:(2007 流行 – 2002 流行)/2002 流行
2003:(2007 流行 – 2002 流行) / 2002 流行
2004: (2007 流行 – 2002 流行) / 2002 流行
2005: (2007 流行 – 2002 流行) / 2002 流行
2006: (2007 流行 – 2002 流行) / 2002 流行
2007: (2012 流行 – 2007 流行) / 2007流行
2008:(2012 流行 - 2007 流行)/ 2007 流行

但是,当我操作 时Growth,我需要按列执行此操作ID。而且,年份的范围是从1970年到2018年,范围很广。我怎样才能做到这一点data.table

标签: rdata.tabledata-manipulation

解决方案


这是一种可能的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]

推荐阅读