|
程序已修改,为测验程序,增加了数据复杂度。
经测试,下面程序可以使用。
data test;
input subjn dt Rx $ x;
cards;
1 1 A 11
1 2 B 12
1 3 C 13
2 3 A 21
2 7 C 22
2 7 B 23
2 12 D 24
2 12 B 25
3 1 B 31
3 1 C 32
3 5 A 33
3 5 C 58
3 8 B 34
3 11 B 35
3 11 D 36
3 11 E 37
4 1 A 41
4 2 B 42
4 2 D 43
4 3 C 44
;run;
%macro test();
proc sql;
drop table t1;
drop table t7;
quit;
proc sql;
create table t1 as
select distinct subjn
from test;
quit;
data _null_;
set t1 nobs=n;
call symput('n', n);
stop;
run;
%do ii = 1 %to &n.;
data _null_;
set t1(firstobs=&ii. obs=&ii.);
call symput('subjn', subjn);
stop;
run;
data t2;
set test;
where subjn = &subjn.;
run;
proc sort data = t2;
by dt rx;
run;
proc sql;
create table t2_only as
select *
from t2
where dt in (select distinct dt from ( select dt, count(*) as cnt from t2 group by dt) where cnt = 1 );
quit;
proc sql;
create table t2_else as
select *
from t2
where dt not in (select dt from t2_only)
order by dt;
quit;
data t2_else;
set t2_else end=eof;
by dt;
if _n_ = 1 then fake_id1 = 0;
if first.dt then fake_id1 + 1;
if eof then call symput('sql_join_times', fake_id1-1);
run;
proc sql noprint;
select count(*) into:flg1 from t2_else;
quit;
%if &flg1. ne 0 %then %do;
proc sql noprint;
select count(distinct fake_id1) into:flg2 from t2_else;
quit;
%if &flg2. = 1 %then %do;
data t3_1(keep=subjn dt_1 rx_1);
set t2_else(rename=(dt=dt_1 rx=rx_1));
output t3_1;
run;
%end;
%do jj = 1 %to &sql_join_times.;
%let name_j1 = %eval(&jj.+0);
%let name_j2 = %eval(&jj.+1);
%if &jj. = 1 %then %do;
data t3_1 t3_2(drop = fake_id1);
set t2_else;
where fake_id1 in (1,2);
if fake_id1 = 1 then output t3_1;
else output t3_2;
run;
proc sql;
create table t4 as
select a.subjn, a.dt as dt_1, a.rx as rx_1, b.dt as dt_2, b.rx as rx_2
from t3_1 as a
full join t3_2 as b
on a.subjn = b.subjn and a.dt < b.dt;
quit;
%end;%else %do;
proc sql;
create table t4 as
select a.*, b.dt as dt_&name_j2., b.rx as rx_&name_j2.
from t3_1 as a
full join t3_2 as b
on a.subjn = b.subjn and a.dt_&name_j1. < b.dt;
quit;
%end;
data t3_1;
set t4;
run;
%if &jj. ne &sql_join_times. %then %do;
data t3_2;
set t2_else;
where fake_id1 = &jj. + 2;
run;
%end;
%end;
data t5_else(keep = subjn dt rx grp);
set t3_1 end=eof;
grp + 1;
%do jj = 1 %to %eval(&sql_join_times.+1);
dt = dt_&jj.;
rx = rx_&jj.;
output;
%end;
if eof then call symput('grp_no', grp);
run;
data t5_only(keep = subjn dt rx grp);
set t2_only;
do grp = 1 to &grp_no.;
output;
end;
run;
data t6;
set t5_only
t5_else;
run;
%end;%else %do;
data t6;
set t2_only(keep = subjn dt rx);
grp = 1;
run;
%end;
proc sort data = t6;
by subjn grp dt rx;
run;
proc append base = t7 data = t6; run;
proc sql;
drop table t2;
drop table t2_only;
drop table t2_else;
drop table t3_1;
drop table t3_2;
drop table t4;
drop table t5_only;
drop table t5_else;
drop table t6;
quit;
%end;
%mend;
%test();
|