【问题标题】:SAS: PROC FREQ combinations automatically?SAS:PROC FREQ 自动组合?
【发布时间】:2018-04-15 21:55:24
【问题描述】:

我有一个如下表所示的患者数据集,我想看看哪些疾病一起出现并最终制作一个热图。我使用 PROC FREQ 制作了这个列表,但是这样处理太费力了,因为它给了我每一个组合(数千个)。

Moya    Hypothyroid Hyperthyroid    Celiac
   1       1           0             0
   1       1           0             0       
   0       0           1             1
   0       0           0             0
   1       1           0             0
   1       0           1             0
   1       1           0             0
   1       1           0             0
   0       0           1             1
   0       0           1             1


proc freq data=new;
tables HOHT*HOGD*CroD*Psor*Viti*CelD*UlcC*AddD*SluE*Rhea*PerA/list;
run;

我最终想要一堆交叉表,如下所示,这样我就可以看到每种组合有多少患者。显然可以像这样手动复制粘贴每个变量,但是有什么方法可以快速查看或自动执行此操作?

proc freq data=new;
tables HOHT*HOGD/list;
run;

proc freq data=new;
tables HOHT*CroD/list;
run;


proc freq data=new;
tables HOHT*Psor/list;
run;

谢谢!

【问题讨论】:

    标签: sas medical


    【解决方案1】:

    可以使用TABLES 语句控制PROC FREQ 中生成的表。要生成数据集中所有列对的 2 路列联表,可以编写一个 SAS 宏,该宏循环遍历变量列表,并生成 TABLES 语句以创建所有正确的列联表。

    例如,使用原始帖子中的数据:

    data xtabs;
    input Moya    Hypothyroid Hyperthyroid    Celiac;
    datalines;
       1       1           0             0
       1       1           0             0       
       0       0           1             1
       0       0           0             0
       1       1           0             0
       1       0           1             0
       1       1           0             0
       1       1           0             0
       0       0           1             1
       0       0           1             1
    ;
    run;
    %macro gentabs(varlist=);
       %let word_count = %sysfunc(countw(&varlist));
       %do i = 1 %to (&word_count - 1);
          tables %scan(&varlist,&i,%str( )) * (
          %do j = %eval(&i + 1) %to &word_count;
            %scan(&varlist,&j,%str( ))
          %end; )
          ; /* end tables statement */
       %end;
    %mend;
    options mprint;
    proc freq data = xtabs;
      %gentabs(varlist=Moya Hypothyroid Hyperthyroid Celiac)
      run;
    

    SAS宏生成的代码是:

     73         proc freq data = xtabs;
     74           %gentabs(varlist=Moya Hypothyroid Hyperthyroid Celiac)
     MPRINT(GENTABS):   tables Moya * ( Hypothyroid Hyperthyroid Celiac ) ;
     MPRINT(GENTABS):   tables Hypothyroid * ( Hyperthyroid Celiac ) ;
     MPRINT(GENTABS):   tables Hyperthyroid * ( Celiac ) ;
     75         run;
    

    ...结果输出中的前几个表如下所示:

    要向TABLES 语句添加选项,可以在注释为/* end tables statement */ 的行的分号前添加代码。

    【讨论】:

    • 哇。感人的。非常感谢
    • @ybao - 不客气。 SAS宏语言绝对值得学习。一开始有点挑战,因为宏语言的输出是 SAS 代码,但你可以用它做一些非常令人印象深刻的事情。
    • 也可以编写一个宏来从SAS数据集中提取列名并将其保存到一个宏变量中,该变量可以用作%gentabs()的参数。
    【解决方案2】:

    Proc MEANS 是一种常用工具,用于获取包含数据的组合组的各种统计信息。在您的情况下,您只需要每个组合的计数。

    假设您有 10,000 名具有 10 个二元因素的患者

    data patient_factors;
      do patient_id = 1 to 10000;
        array factor(10);
        do _n_ = 1 to dim(factor);
          factor(_n_) = ranuni(123) < _n_/(dim(factor)+3);
        end;
        output;
      end;
      format factor: 4.;
    run;
    

    正如您所提到的,Proc FREQ 可以计算每个 10 级组合的计数。

    proc freq noprint data=patient_factors;
      table 
        factor1
        * factor2 
          * factor3
            * factor4
              * factor5
                * factor6
                  * factor7
                    * factor8
                      * factor9
                        * factor10
      / out = pf_10deep
      ;
    run;
    

    FREQ 没有语法来支持创建包含涉及factor1 的每个成对组合的输出数据。

    Proc MEANS 确实具有此类输出的语法。

    proc means noprint data=patient_factors;
      class factor1-factor10;
      output out=counts_paired_with_factor1 n=n;
      types factor1 * ( factor2 - factor10 );
    run;
    

    【讨论】:

    • 其实PROC FREQ确实支持TABLES factor1 * (factor2 -- factor10);这样的语法。请参阅 SAS/STAT 14.3 用户指南的第 2796 页
    • 是的,确实,表格会创建所有交叉点的 ODS 输出,但我相信 'FREQ' 中的 output=(作为数据)创建的数据集将只是最后解决的交叉点。
    猜你喜欢
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多