【问题标题】:SAS macro to print out change of baseline scoresSAS 宏打印出基线分数的变化
【发布时间】:2019-07-01 13:31:37
【问题描述】:

我正在寻找一种使用 SAS 宏打印出每个科目的考试分数变化的方法。以下是数据示例:

Subject    Visit       Date       Test       Score
001        Baseline    01/01/99   Jump       5
001        Baseline    01/01/99   Reach      3
001        Week 6      02/12/99   Jump       7
001        Week 6      02/12/99   Reach      6
002        Baseline    03/01/99   Jump       2
002        Baseline    03/01/99   Reach      4
002        Week 6      04/12/99   Jump       5
002        Week 6      04/12/99   Reach      9

我想创建一个宏,为每个主题生成以下内容:

Subject    Visit       Date (Days from Baseline)       Test       Score    Change from Baseline Score
001        Baseline    01/01/99                        Jump       5         
                       01/01/99                        Reach      3         
001        Week 6      02/12/99    (42)                Jump       7        +2
                       02/12/99    (42)                Reach      6        +3
002        Baseline    03/01/99                        Jump       2
                       03/01/99                        Reach      4
002        Week 6      04/12/99    (42)                Jump       5        +3
                       04/12/99    (42)                Reach      9        +5

我相信我可以将 INTCK 函数用于从基线开始的天数,但我不确定如何在不保留每行中的“主题”和“访问”值的情况下打印每个测试。任何帮助将非常感激。

【问题讨论】:

    标签: arrays loops sas


    【解决方案1】:

    您可以使用保留日期和分数来计算增量,按测试和流程进行排序。可以使用Proc REPORT 打印输出,适当地格式化增量值。

    例子:

    data have; input 
    Subject    Visit& $8.  Date& mmddyy8. Test $ Score; format date mmddyy8.; datalines;
    001        Baseline    01/01/99   Jump       5
    001        Baseline    01/01/99   Reach      3
    001        Week 6      02/12/99   Jump       7
    001        Week 6      02/12/99   Reach      6
    002        Baseline    03/01/99   Jump       2
    002        Baseline    03/01/99   Reach      4
    002        Week 6      04/12/99   Jump       5
    002        Week 6      04/12/99   Reach      9
    run;
    
    proc sort data=have;
      by subject test date;
    run;
    
    data for_report;
    
      set have;
      by subject test;
    
      retain base_date base_score;
    
      if first.subject then do;
        base_date = .;
        base_score = .;
      end;
    
      if first.test and visit='Baseline' then do;
        base_date = date;
        base_score = score;
      end;
    
      if not first.test then do;
        delta_days = intck('days', date, base_date);
        delta_score = score - base_score;
      end;
    
    run;
    
    
    proc format;
      picture plus low-0 = [best12.] other = '000000009' (prefix='+');
    
    options missing=' ';
    proc report data=for_report;
      columns subject visit date delta_days test score delta_score;
      define subject / order;
      define visit / order order=data;
      format delta_days negparen.; 
      format delta_score plus.;
    run;
    options missing='.';
    

    替代报告可以更加以主题为中心:

    proc report data=for_report
      style(lines) = [just=left fontweight=bold]
    ;
      columns subject visit date delta_days test score delta_score;
      define subject / order noprint;
      define visit / order order=data;
      format delta_days negparen.; 
      format delta_score plus.;
      compute before subject;
        subj = catx(' ', "Subject:", subject);
        line subj $200.;
      endcomp;
    run;
    

    【讨论】:

      【解决方案2】:

      这是一种方法。 SQL 步骤从基线计算变化。 case-when-construct 仅用于抑制输出中的零。

      在 proc 报告中使用组变量进行打印意味着主题值和访问值不会保留在每一行(但请注意主题每周不会重复)。

      我将代码放在宏中,因为这就是问题所在。然而,它并没有真正起到什么作用。

      /*  Creating test data*/
      data testdata;
          input Subject $3.  @5 Visit $8.  @17 Date mmddyy10. @28 Test $5. Score;
          format date mmddyy10.;
      datalines;
      001 Baseline    01/01/99   Jump       5
      001 Baseline    01/01/99   Reach      3
      001 Week 6      02/12/99   Jump       7
      001 Week 6      02/12/99   Reach      6
      002 Baseline    03/01/99   Jump       2
      002 Baseline    03/01/99   Reach      4
      002 Week 6      04/12/99   Jump       5
      002 Week 6      04/12/99   Reach      9
      ;
      
      %macro baselines(dataset=);
          /*  Adding days from baseline and change from baseline. Please note that the first visit 
          must denoted as exactly "Baseline"*/
          proc sql;
              create table changes as 
              select t1.*, case when t1.date-t2.date>0 then t1.date-t2.date else . end  as days 
                  "Days from baseline", case when t1.score-t2.score>0 then t1.score-t2.score else . 
                  end as score_change "Change from Baseline"
              from &dataset as t1 left join (select * from &dataset where visit="Baseline") as t2
                  on t1.subject=t2.subject and t1.test=t2.test
              order by subject, visit, test;
      
          /*  Printing the dataset. The use of subject and visit as group variables keeps SAS from repeating the values*/
          title "Changes based on the dataset &dataset";
          proc report data=changes;
              column subject visit days test score score_change;
              define subject / group;
              define visit / group;
          run;
      %mend;
      %baselines(dataset=testdata)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多