三、解决办法:
问题解析:目的是想实现 第一个病人的第一次就诊时的手术标识为1,第二次就诊时的手术标识为2,....,第n次就诊时的手术标识为n。
步骤一:这时不仅有病人这个组,还有就诊这个组,而且我们可以观察到,当FIRST_PID=1时就是这个病人的第一条手术记录,当FIRST_PID=0,FIRST_VID=1时是这个病人其他后续就诊中的第一条手术记录,此时,这条记录的手术标识应该=上一次就诊的手术标识+1,即:
/*手术次序1*/
proc sort data=surgery;
by PID VID;
run;
data surgery_ord;
set surgery;
by PID VID;
first_PID=first.PID;
first_VID=first.VID;
if first.PID then surgery_order=1;
else if first.VID then surgery_order=surgery_order+1;
run;
proc print data=surgery_ord;
run;
Obs PID VID first_PID first_VID surgery_order
1 1 A 1 1 1
2 1 B 0 1 .
3 1 B 0 0 .
4 1 C 0 1 .
5 2 D 1 1 1
6 2 D 0 0 .
7 2 E 0 1 .
但结果还不是我们想要的,因为SAS开始处理每一行时,都会将变量初始化为缺失,所以在处理第二行first_PID=0,first_VID=1数据时,surgery_order为缺失,所以进行surgery_order=surgery_order+1,结果仍为缺失。此时可以利用retain语句,避免surgery_order被初始化。所以就需要步骤二。
步骤二:解法一:其他同次就诊中的手术标识与该次就诊中的第一条记录相同,所以结合retain语句,可以将问题以如下方式解决:
/*手术次序2*/
proc sort data=surgery;
by PID VID;
run;
data surgery_ord;
set surgery;
retain surgery_order;
by PID VID;
first_PID=first.PID;
first_VID=first.VID;
if first.PID then surgery_order=1;
else if first.VID then surgery_order=surgery_order+1;
run;
proc print data=surgery_ord;
run;
Obs PID VID surgery_order first_PID first_VID
1 1 A 1 1 1
2 1 B 2 0 1
3 1 B 2 0 0
4 1 C 3 0 1
5 2 D 1 1 1
6 2 D 1 0 0
7 2 E 2 0 1

也可以不使用retain语句,而是将surgery_order变量放在累加语句中使用,累加语句中的变量不会被初始化,作用类似retain:
/*手术次序2*/
proc sort data=surgery;
by PID VID;
run;
data surgery_ord;
set surgery;
by PID VID;
first_PID=first.PID;
first_VID=first.VID;
if first.PID then surgery_order=1;
else if first.VID then surgery_order+1;
run;
proc print data=surgery_ord;
run;
Obs PID VID first_PID first_VID surgery_order
1 1 A 1 1 1
2 1 B 0 1 2
3 1 B 0 0 2
4 1 C 0 1 3
5 2 D 1 1 1
6 2 D 0 0 1
7 2 E 0 1 2
如果对累加语句不好理解,可以查看以下代码:
data surgery_ord;
set surgery;
by PID VID;
PUT "Before the process statement: " _ALL_;
if first.PID then surgery_order=1;
else if first.VID then surgery_order+1;
PUT "after the process statement: " _ALL_/;
run;
可以看到,累加语句中,surgery_ord这个变量是不会被初始化的。