Reputation: 4434
I tried to use macro and array to lag a bunch of variables by groups (id). my steps are:
1. lag all variables (groups not matter)
2. replace mis-lagged cells by .
but I found my code is buggy and appreciate any suggestions.
Here is the data:
data old;
input id sale capx profit;
datalines;
1 11 111 1111
1 12 112 1112
1 13 113 1113
1 14 114 1114
1 15 115 1115
1 16 116 1116
1 17 117 1117
2 21 221 2221
2 22 222 2222
2 23 223 2223
3 31 331 3331
3 32 332 3332
3 33 333 3333
3 34 334 3334
4 41 441 4441
4 42 442 4442
4 43 443 4443
4 44 444 4444
4 45 445 4445
4 46 446 4446
;
run;
Code:
data new;
set old;
run;
%macro lag_var(dataset, lag);
proc sort data=&dataset;by id;
data &dataset;
set &dataset;
by id;
array vs(3) sale capx profit;
%do j=1 %to 3;
%do i=1 %to &lag;
lag&j&i=lag&i(vs(&j));
if first.id then
do;
count=1;
lag&j&i=.;
end;
count+1;
if (not first.id and count<=&i) then
do;
lag&j&i=.;
count+1;
end;
%end;
%end;
run;
%mend lag_var;
%lag_var(new,5)
Current output (wrong):
My expected results:
DomPazz's output:
Upvotes: 1
Views: 2846
Reputation: 12465
The reason those later groups are keeping their value is that you are over incrementing count
.
I think this does what you are looking for:
%macro lag_var(dataset, lag);
proc sort data=&dataset;by id;
data &dataset;
set &dataset;
by id;
array vs(3) sale capx profit;
%do j=1 %to 3;
%do i=1 %to &lag;
lag&j&i=lag&i(vs(&j));
%end;
%end;
if first.id then do;
count=0;
%do j=1 %to 3;
%do i=1 %to &lag;
lag&j&i=.;
%end;
%end;
end;
count+1;
%do j=1 %to 3;
%do i=1 %to &lag;
if (not first.id and count<=&i) then do;
lag&j&i=.;
/*count+1;*/
end;
%end;
%end;
run;
%mend lag_var;
EDIT: Changed the initialization of count from 1 to 0.
Upvotes: 2