【问题标题】:Using PROC SORT and DATA _NULL_ to produce report with SAS使用 PROC SORT 和 DATA _NULL_ 使用 SAS 生成报告
【发布时间】:2014-10-30 04:26:51
【问题描述】:

(注意:这是我有正确答案的家庭作业,但我对结果不满意。)

关于数据的一点上下文。四种药物中每种药物的信息都记录在患者来诊所就诊时:代码 0 表示未服用药物,代码 1 表示正在开始服用药物,代码 2 表示正在服用药物停产。对于每次就诊,都会记录患者 ID、就诊日期和四种药物的状态代码。

我的目标是只使用PROC SORTDATA _NULL_ 程序来生成报告。我已经成功地在DATA _NULL_ 步骤中使用PUT 语句来创建使用过所有处方药的个人列表,但是我将如何生成一份报告,显示使用过所有处方药的个人总数?

电流输出

患者 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;

【问题讨论】:

    标签: sas datastep


    【解决方案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;
    

    【讨论】:

    • 感谢您的帮助。那里有很多不必要的代码,部分是因为我需要找到其他总数,但主要是因为我不知道我在做什么,并且想一路使用 PROC PRINT 检查我的结果。至于 %eval() 语句,我不确定我是否只输入 %let num_rx_var = 4,SAS 会知道 4 是数字而不是字符值。我想我应该尝试一下。
    • 所有宏变量都是文本——既不是数字也不是字符。它们就像您手动输入的一样。但当用作x=&mvar.; 时,它们实际上是数字常量[或变量名或其他未引用的内容],因为您需要引用它们 (x="&mvar.") 以使它们成为字符常量。
    猜你喜欢
    • 2013-02-17
    • 2022-12-18
    • 1970-01-01
    • 2021-04-25
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    相关资源
    最近更新 更多