首页 > 解决方案 > 具有滞后项的两列之和

问题描述

假设我有一个这样的 data.frame:

dt=data.frame(id=rep(letters[1:3],each=4),
          year=rep(1:4,3),
          invest=1:12,
          y=rep(c(1,0,0,0),3)) 
dt
   id year invest y
1   a    1      1 1
2   a    2      2 0
3   a    3      3 0
4   a    4      4 0
5   b    1      5 1
6   b    2      6 0
7   b    3      7 0
8   b    4      8 0
9   c    1      9 1
10  c    2     10 0
11  c    3     11 0
12  c    4     12 0

我想获得一个新列 y2:y2=lag.y2 * 0.8 + 投资,并且第一年的 y2 等于 y 按组。像这样:

id  year invest y   y2
a   1    1      1   1
a   2    2      0   2.8
a   3    3      0   5.24
a   4    4      0   8.192
b   1    5      1   1
b   2    6      0   6.8
b   3    7      0   12.44
b   4    8      0   17.952
c   1    9      1   1
c   2    10     0   10.8
c   3    11     0   19.64
c   4    12     0   27.712

谢谢!

标签: rdplyrdata.table

解决方案


您可以使用Reduce以下递归方式计算:

library(data.table)
setDT(dt)[, y2 := Reduce(function(y, inv) inv + y * 0.8, 
        invest[-1L], init=y[1L], accumulate=TRUE), 
    by=.(id)]

Rcpp用于进一步提高效率:

library(Rcpp)
cppFunction(
"NumericVector func(double y0, NumericVector invest) {
    NumericVector res(invest.size());
    res[0] = y0;
    for (int i=1; i<invest.size(); i++) {
        res[i] = 0.8*res[i-1] + invest[i];
    }
    return res;
}")
dt$y2 <- unlist(by(dt, dt$id, function(x) func(x$y[1L], x$invest)))

输出:

    id year invest y     y2
 1:  a    1      1 1  1.000
 2:  a    2      2 0  2.800
 3:  a    3      3 0  5.240
 4:  a    4      4 0  8.192
 5:  b    1      5 1  1.000
 6:  b    2      6 0  6.800
 7:  b    3      7 0 12.440
 8:  b    4      8 0 17.952
 9:  c    1      9 1  1.000
10:  c    2     10 0 10.800
11:  c    3     11 0 19.640
12:  c    4     12 0 27.712

推荐阅读