我在 SAS 中有一个包含每日数据的数据集。我想通过 id 与上个月的值不同,将其转换为月度形式。例如:
thedate, id, val
2012-01-01, 1, 10
2012-01-01, 2, 14
2012-01-02, 1, 11
2012-01-02, 2, 12
...
2012-02-01, 1, 20
2012-02-01, 2, 15
我想输出:
thedate, id, val
2012-02-01, 1, 10
2012-02-01, 2, 1
我在 SAS 中有一个包含每日数据的数据集。我想通过 id 与上个月的值不同,将其转换为月度形式。例如:
thedate, id, val
2012-01-01, 1, 10
2012-01-01, 2, 14
2012-01-02, 1, 11
2012-01-02, 2, 12
...
2012-02-01, 1, 20
2012-02-01, 2, 15
我想输出:
thedate, id, val
2012-02-01, 1, 10
2012-02-01, 2, 1
这是一种方法。如果您获得 SAS-ETS 的许可,则使用 PROC EXPAND 可能会有更好的方法。
*Setting up the dataset initially;
data have;
informat thedate YYMMDD10.;
input thedate id val;
datalines;
2012-01-01 1 10
2012-01-01 2 14
2012-01-02 1 11
2012-01-02 2 12
2012-02-01 1 20
2012-02-01 2 15
;;;;
run;
*Sorting by ID and DATE so it is in the right order;
proc sort data=have;
by id thedate;
run;
data want;
set have;
retain lastval; *This is retained from record to record, so the value carries down;
by id thedate;
if (first.id) or (last.id) or (day(thedate)=1); *The only records of interest - the first record, the last record, and any record that is the first of a month.;
* To do END: if (first.id) or (last.id) or (thedate=intnx('MONTH',thedate,0,'E'));
if first.id then call missing(lastval); *Each time ID changes, reset lastval to missing;
if missing(lastval) then output; *This will be true for the first record of each ID only - put that record out without changes;
else do;
val = val-lastval; *set val to the new value (current value minus retained value);
output; *put the record out;
end;
lastval=sum(val,lastval); *this value is for the next record;
run;
您可以使用 PROC SQL 和 intnx 函数将上个月的日期提前一个月来实现这一点......
过程 sql ; 创建表滞后为 选择 b.thedate, b.id, (b.val - a.val) 作为 val 来自我的数据 b 左连接 mydata a on b.date = intnx('month',a.date,1,'s') 和 b.id = a.id 按 b.date、b.id 排序; 辞职 ;
这可能需要调整以处理上个月不存在或与上个月有不同天数的月份的情况。