(注意:这是一个家庭作业,我有正确的答案,但我对结果不满意。)
关于数据的一些背景。记录患者进入门诊时四种药物的信息:代码为0表示药物未被服用,代码为1表示药物正在开始,代码为2表示药物正在进行停产。对于每次访问,记录患者ID,访问日期和四种药物的状态代码。
我的目标是仅使用PROC SORT
和DATA _NULL_
程序来生成报告。我在PUT
步骤中使用DATA _NULL_
语句成功创建了一份使用过所有处方药的个人名单,但是我如何制作一份报告,显示所有人的总人数用过所有处方药吗?
患者01服用了4种不同的药物 患者03服用了4种不同的药物 患者04服用了4种不同的药物
有3名患者服用了4种不同的药物。
DATA drug;
Input ID : $2. Visit : MMDDYY8. rx_1-rx_4;
Datalines;
04 01/28/95 1 0 1 1
03 02/28/95 2 0 2 1
05 05/20/95 0 0 0 0
01 03/27/95 1 0 0 1
03 03/02/95 0 0 0 1
01 04/04/95 0 1 1 1
02 04/29/95 0 1 1 1
02 05/04/95 0 0 1 0
03 02/26/95 1 0 1 1
03 03/06/95 0 1 0 1
04 01/25/95 0 0 1 0
05 03/01/95 0 0 0 0
02 04/30/95 0 2 1 2
01 03/31/95 2 1 0 1
03 03/07/95 0 1 0 2
04 02/01/95 1 1 1 1
05 04/18/95 0 0 0 0
01 04/09/95 0 2 1 2
;
PROC SORT Data = Drug;
By id visit;
RUN;
%let num_rx_var = %eval(4);
DATA _null_;
File Print;
Set drug;
By id;
Array
rx_indicator{&num_rx_var} rx_1-rx_4;
Array
takes_rx_{&num_rx_var} (&num_rx_var*0);
Array
has_taken_rx_{&num_rx_var} (&num_rx_var*0);
Do i=1 To &num_rx_var;
takes_rx_{i} = 0;
End;
Do i=1 To &num_rx_var;
takes_rx_{i} = takes_rx_{i} or (rx_indicator{i}>0);
sum_dif_rx_visit = sum(of takes_rx_{*});
End;
If first.id Then
Do i=1 To &num_rx_var;
has_taken_rx_{i} = 0;
End;
Do i=1 To &num_rx_var;
has_taken_rx_{i} = has_taken_rx_{i} or (rx_indicator{i}>0);
End;
If last.id Then Do;
num_diff_rx = sum(of has_taken_rx_{*});
End;
all_drugs = count(num_diff_rx, &num_rx_var);
If all_drugs = 1 Then Put "Patient " id "has taken " num_diff_rx "different drugs" ;
RUN;
答案 0 :(得分:1)
以下是我如何做到这一点,试图坚持你主要做的事情。
你有很多额外的东西,你真的不需要。我不知道为什么你在结尾使用COUNT
(一个字符函数)。也不确定为什么你在宏变量中使用%eval()
- 这没有做任何事情。不知道takes
数组正在做什么 - 那还有什么吗?
总的来说,虽然你的方法非常合理。如果您的数据结构更好,那么使用update
语句会很容易,如果0
改为.
。我不确定2
在这里的重要性,你似乎无视它;有意义的是,2
的药物也必须在1
某个点,但谁知道呢。
找出总患者服用所有药物的总数的一般方法是在最后if
(验证所有药物都被服用)中添加一个计数器变量,然后在输出中使用它。 x+1;
创建一个计数器,并自动保留它。
%let num_rx_var = 4;
DATA test;
File Print;
Set drug end=eof; *note small change here - sets `eof=1` on last row.;
By id;
array rx rx_1-rx_&num_rx_var;
array rx_flag[&num_rx_var] _temporary_;
*Temporary array variables are automatically retained;
if first.id then
call missing(of rx_flag[*]); *clear the flags for a new ID;
do _i = 1 to dim(rx); *use your OR construct, that is fine;
rx_flag[_i] = rx_flag[_i] or rx[_i];
end;
if last.id then do;
sum_drugs = sum(of rx_flag[*]); *check if the sum of the flags equals number of flags;
*there is a more fun way to do this using `whichn`;
if sum_drugs = dim(rx_flag) then do;
num_total +1; *increment our counter;
put "Patient " id "has taken " sum_drugs "different drugs.";
end;
end;
if eof then /* Use our counter only on the last row of the dataset */
put num_total "Patients have taken &num_rx_Var. different drugs.";
RUN;