根据先前计算的行 SAS 计算行值

问题描述

我有一个 SAS 数据集,其整体结构与以下类似。我想根据每个 ID(学生)上个月的 MONEY 和 SPEND 计算 MONEY 列中的所有“缺失”值。

我的数据如下所示 (INPUT_DATA):

ID        MONTH       MONEY      SPEND  
01            1        1000        300
01            2           .        200
01            3           .        200
01            4           .        300
02            1        2000        100
02            2           .        100
02            3           .        150
02            4           .        100
03            1         900        600
03            2           .        100
03            3           .        200

我希望它看起来像这样 (OUTPUT_DATA):

ID        MONTH       MONEY      SPEND  
01            1        1000        300
01            2         700        200
01            3         500        200
01            4         300        300
02            1        2000        100
02            2        1900        100
02            3        1800        150
02            4        1650        100
03            1         900        600
03            2         300        100
03            3         200        200

这怎么可能使用 SAS?我使用 LAG 函数尝试了类似的操作:

DATA OUTPUT_DATA;
    SET INPUT_DATA;
    IF MONTH > 1 THEN MONEY = LAG1(MONEY) - LAG1(SPEND);
RUN;

但不幸的是,它没有返回预期的输出。可以使用以下方法创建数据:

data INPUT_DATA;
  infile datalines;
  input ID MONTH MONEY SPEND;
datalines;
01            1        1000        300
01            2           .        200
01            3           .        200
01            4           .        300
02            1        2000        100
02            2           .        100
02            3           .        150
02            4           .        100
03            1         900        600
03            2           .        100
03            3           .        200
;
run;

解决方法

如果您创建一个保留的新变量,可能会更容易。

data have;
  input ID $ MONTH MONEY SPEND  ;
cards;
01 1 1000 300
01 2    . 200
01 3    . 200
01 4    . 300
02 1 2000 100
02 2    . 100
02 3    . 150
02 4    . 100
03 1  900 600
03 2    . 100
03 3    . 200
;

data want;
  set have ;
  by id;
  new_money = coalesce(money,new_money);
  output;
  new_money + -spend;
run;

结果:

                                         new_
Obs    ID    MONTH    MONEY    SPEND    money

  1    01      1       1000     300      1000
  2    01      2          .     200       700
  3    01      3          .     200       500
  4    01      4          .     300       300
  5    02      1       2000     100      2000
  6    02      2          .     100      1900
  7    02      3          .     150      1800
  8    02      4          .     100      1650
  9    03      1        900     600       900
 10    03      2          .     100       300
 11    03      3          .     200       200

如果您想删除原始变量并重新使用其名称,请添加 DROP 和 RENAME 语句。

drop money;
rename new_money=money;