Hello,
This is not elegant but it works.
It should be possible to write code for this that is much more concise.
options mprint;
PROC DATASETS library=work NOLIST;
delete test: / memtype=DATA;
delete out: / memtype=DATA;
run;
data test;
input ID jan2006v1 feb2006v1 mar2006v1 jan2006v2 feb2006v2 mar2006v2;
datalines;
1 -1 . . 5 . .
2 . 2 . . 3 .
3 . . 2 . . 5
4 2 -3 1 4 6 5
5 . 1 2 . 4 3
;
run;
%MACRO ARRAYv1v2;
array v1{*} jan2006v1--mar2006v1;
array v2{*} jan2006v2--mar2006v2;
%MEND ARRAYv1v2;
/* transpose to get the non-missing "MY v1a v2a" couples */
data test1;
LENGTH ID 8 MY $ 7 i 8 v1a 8 v2a 8;
set test;
%ARRAYv1v2
do i=1 to dim(v2);
v1a = v1{i};
v2a = v2{i};
MY = substr(vname(v1{i}),1,7);
*if NOT (v1a=. AND v2a=.) then output;
if v1a^=. then output;
end;
run;
data test2;
set test1(drop=i);
%ARRAYv1v2
do i=1 to dim(v2);
if substr(vname(v1{i}),1,7) NE MY then do; v1{i}=.; v2{i}=.; end;
end;
run;
data out1 out2;
set test2(drop=i);
%ARRAYv1v2
/*
if v2a in (5,6) and (v1a + v2a) in (1,2,3,4) then output out1;
if v2a in (1,2,3,4) and (v1a + v2a) in (5,6) then output out2;
*/
/* WE NEED i */
do i=1 to dim(v2);
if v2{i} in (5,6) and (v1{i} + v2{i}) in (1,2,3,4) then output out1;
if v2{i} in (1,2,3,4) and (v1{i} + v2{i}) in (5,6) then output out2;
end;
run;
%MACRO out1out2;
%DO k=1 %TO 2;
proc sort data=out&k.; by ID i; run;
/* COLLAPSE rows with same ID */
data out&k.(drop=jan2006v1--mar2006v1 jan2006v2--mar2006v2 i j MY v1a v2a);
set out&k.;
by ID i;
%ARRAYv1v2
array v1b{*} jan2006v1b feb2006v1b mar2006v1b;
array v2b{*} jan2006v2b feb2006v2b mar2006v2b;
retain jan2006v1b feb2006v1b mar2006v1b;
retain jan2006v2b feb2006v2b mar2006v2b;
if first.ID then do j=1 to dim(v2); v1b{j}=.; v2b{j}=.; end;
if v1{i}^=. then v1b{i}=v1{i};
if v2{i}^=. then v2b{i}=v2{i};
if last.ID then output;
run;
%END; /* %DO k=1 to 2; */
%MEND out1out2;
%out1out2
/* end of program */
Cheers,
Koen
... View more