美文网首页js css html
SAS编程-Table:层级拼接法输出AE SOC、PT的受试者

SAS编程-Table:层级拼接法输出AE SOC、PT的受试者

作者: 野藤_ | 来源:发表于2022-05-03 11:45 被阅读0次

    之前的文章SAS编程:按SOC和PT类别汇总AE的受试者发生率 介绍了一种输出AE受试者发生率的方法,是通过各层级单独计算后,再统一汇总输出。

    前面文章SAS编程-Table:层级关系的频数汇总处理 ——层级拼接法也介绍了具有层级关系的频数汇总表,可以使用层级拼接法进行输出。

    这篇文章使用层级拼接法输出SOC和PT嵌套汇总表格,与单独计算各层级再汇总输出相比,层级拼接法效率要高很多。条件大家尝试使用。

    层级拼接处理在文章2.3、2.5、2.6部分有详细描述,第3部分有主体程序代码的汇总。AE相关的去重在2.3部分,计算小n的人群获取时进行处理。

    关于嵌套Table统计量的介绍、SOC和PT的具体含义,在第一篇文章中有过详细说明,这里不再具体介绍。

    需要明确一点,受试者的发生率是“人数比人数”,所以我们所有的计数都是基于“数人数”的前提

    直接看示例。

    1. 具体示例

    AE-SOCPT

    以上就是一张普通的AE受试者发生率的SOC、PT嵌套的频数汇总表。人群是Safety Analysis Set,对应至少有一次给药记录的受试者,试验分组应采用实际用药分组

    2. SAS代码演示

    首先,附上我的QC“5段论”:

    ***1. Create formats for output;
    ***2. Get data for analysis;
    ***3. Calculate statistics;
    ***4. Create dataset for QC;
    ***5. Compare;

    2.1 汇总组的设置

    举例示例有两个试验分组,对应的trt01an的值为450、451。

    这次演示加上汇总组(Total),我会采用Format过程步中multilabel选项进行实现,具体内容可以参考SAS编程:生成Table时,汇总组(Total)组如何处理?

    用于Means过程步Preloadfmt选项的受试者分组Format设置如下:

    ***1. Craete Formats for output;
    proc format;
      value trt01an(notsorted multilabel)
        450 = 450
        451 = 451
        450, 451 = 999 /*For total*/
      ;
    run;
    
    2.2 计算BigN的人群获取

    BigN人群取saffl = "Y"的人群。

    ***2. Get data for analysis;
    
    **2,1 Get data for BigN;
    data adsl;
      set adam.adsl;
      where saffl= "Y";
    
      *Flag for count;
      flag = 1;
    run;
    
    2.3 计算小n的人群获取——层级拼接

    计算小n的人群是在BigN人群范围之内,SAP中通常都是要求分析Treatment-emergent Adverse Events,需要添加对应的Flag条件aetrtem = "Y"

    收集的AETERM可能没有对应的标准编码值,在AEBODSYS、AEDECOD为空的情况下,需要手动补充缺失值。

    一条AE记录的3类信息会被计数 (Reporting TEAE、SOC、PT),利用Output语句将1条记录输出为3条,每一条对应需要计数的那一类信息

    为了方便层级信息分类和排序,新生成的记录需要包含对应的层级关系。AE的层级关系,不像Region、Country、Site那样,可以通过感叹号数量进行判断,于是我添加序号来确认层级。

    在数据中只有1个SOC的情况下,第1层级和第2层级频数是相同的,需要进一步用序号来区分排列顺序。对于第2层级和第3层级,"!"||strip(aedecod)可以自动区分字符顺序,因此序号赋值为相同值。

    受试者发生率的计算是基于“人数比人数”,每一个条目只需要保留受试者的一条信息。如果某个AE,受试者发生多次,计数时也“只算1人”,所以需要对受试者去重。

    **2.2 Get data for small n;
    data adae;
      merge adam.adae(in = a) adsl(in = b);
      by usubjid;
    
      if a and b and aetrtem = "Y";
    
      *Set for missing values;
      if missing(aebodsys) then aebodsys = "Missing system organ class";
      if missing(aedecod) then aedecod = "Missing preferred term";
      
      *Combine all categories in one variable;
      length cat $200;
      
      cat = "01!"||"Number of subjects reporting treatment-emergent adverse events"; output;
      cat = "02!"||strip(aebodsys); output;
      cat = "02!"||strip(aebodsys)||"!"||strip(aedecod); output;
    
      proc sort nodupkey;
        by cat usubjid;
    run;
    
    2.4 计算BigN

    处理好分析数据后,BigN的计算与之前的文章一样:

    ***3. Calculate statistics;
    
    **3.1 Derive BigN and save them to macro vars; 
    proc means data =adsl nway completetypes;
      format trt01an trt01an.;
      class trt01an/ preloadfmt mlf order = data; 
      var flag;
      output n = bign nmiss = nmiss out = BigN; 
    run;
    
    data _null_;
      set BigN;
      call symputx("N_"||strip(trt01an), put(bign,best.)); 
    run;
    
    data check_bign;
      set sashelp.vmacro;
      where index(name, "N_") and length(name)<=6;
      keep name value; 
    run;
    
    2.5 计算小n

    小n的计算也与之前文章大体类似,只是不需要为分析变量cat提前设置Format。

    **3.2 Calculate small n and percentage;
    
    *Get small n;
    proc means data = adae nway completetypes;
      format trt01an trt01an.;
      class trt01an/ preloadfmt mlf order = data;
    
      class cat;
    
      var flag;
      output n = count nmiss = nmiss out = count1; 
    run;
    
    *Get percentage; 
    data count2;
      merge count1 bign; 
      by trt01an;
      length freq $200;
      if bign ne 0 then freq = strip(put(count,best.))||" ("||strip(put(count/bigN*100,8.1)) ||")";
      else freq = "0 (-)";
    
      proc sort;
        by cat trt01an;
    run;
    
    *Transpose results;
    proc transpose data = count2 out = count3 prefix= trt_ ;
      by cat; 
      var freq; 
      id trt01an; 
    run;
    

    百分比处理完毕后,下面要对第一列的内容进行处理。计数时,是按拼接后的变量信息计数。计数完毕后,需要根据所在层级输出第一列的内容。而所在层级是通过所赋值序号以及所含感叹号数量进行判断。

    data final1;
      set count3;
    
      length c1 - c4 $200;
    
      if index(cat, "01")  then c1 = scan(cat, 2, "!");
      else if index(cat, "02")  then c1 = scan(cat, 2, "!");
      else if index(cat, "03")  then c1 = scan(cat, 3, "!");
    
      c2 = trt_450;
      c3 = trt_451;
      c4 = trt_999;
      
      keep c:;
    
      proc sort;
        by cat;
    run;
    

    输出结果如下:

    Results

    目前,排序是按SOC、PT的字母顺序进行排序的,AE嵌套表格都是需要按某试验组频数降序排序

    需要进一步处理。

    2.6 按汇总列频数降序排序

    这一步,主要操作是为每一个层级附上对应的汇总列频数,通过BY语句、Retain语句为组内赋值实现

    严格说来,AE的这张嵌套表格只有SOC和PT两个层级,可以新建变量CAT1、CAT2加以区分。

    在只有一个SOC的情况下,即“Number of subjects reporting treatment-emergent adverse events”和SOC频数相同的情况下,为确保“Number of subjects”排在首行,将其对应的cat1、cat2置空。

    这里的处理跟Region、Country、Site层级汇总表有点不同,后者字符排序就可以区分前两个层级,不需要额外处理,读者可以结合两者CAT变量的衍生理解下。

    为SOC和PT新建一个分组变量 (cat1, cat2),并按层级分组排序

    *Create group vars;
    data final1;
      set count3;
    
      length c1 - c4 $200;
    
      if index(cat, "01")  then c1 = scan(cat, 2, "!");
      else if index(cat, "02") and count(cat, "!") = 1 then c1 = scan(cat, 2, "!");
      else if index(cat, "02") and count(cat, "!") = 2 then c1 = scan(cat, 3, "!");
    
      c2 = trt_450;
      c3 = trt_451;
      c4 = trt_999;
    
      *For freqency sort;
      num = input(scan(c4,1,"("), best.);
    
      cat1 = scan(cat, 2, "!");
      cat2 = scan(cat, 3, "!");
    
      if index(cat, "01") then call missing(of cat1-cat2);
      
      keep num c:;
    
      proc sort;
        by cat1 cat2;
    run;
    

    为每一分组赋上组内汇总频数 (cat1n, cat2n),并以频数降序、相同频数以字母顺序升序排列

    *Get counts for the group vars;
    data final2;
      set final1;
      by cat1 cat2;
    
      retain cat1n cat2n;
    
      if first.cat1 then cat1n = num;
      if first.cat2 then cat2n = num;
    
      proc sort;
        by descending cat1n cat1 descending cat2n cat2;
    run;
    

    输出结果如下:

    Results 2

    这个就是输出结果的主体部分。

    3. 主体程序代码汇总:

    ***1. Craete Formats for output;
    proc format;
      value trt01an(notsorted multilabel)
        450 = 450
        451 = 451
        450, 451 = 999 /*For total*/
      ;
    run;
    
    
    ***2. Get data for analysis;
    
    **2,1 Get data for BigN;
    data adsl;
      set adam.adsl;
      where saffl= "Y";
    
      *Flag for count;
      flag = 1;
    run;
    
    **2.2 Get data for small n;
    data adae;
      merge adam.adae(in = a) adsl(in = b);
      by usubjid;
    
      if a and b and aetrtem = "Y";
    
      *Set for missing values;
      if missing(aebodsys) then aebodsys = "Missing system organ class";
      if missing(aedecod) then aedecod = "Missing preferred term";
      
      *Combine all categories in one variable;
      length cat $200;
      
      cat = "01!"||"Number of subjects reporting treatment-emergent adverse events"; output;
      cat = "02!"||strip(aebodsys); output;
      cat = "02!"||strip(aebodsys)||"!"||strip(aedecod); output;
    
      proc sort nodupkey;
        by cat usubjid;
    run;
    
    
    ***3. Calculate statistics;
    
    **3.1 Derive BigN and save them to macro vars; 
    proc means data =adsl nway completetypes;
      format trt01an trt01an.;
      class trt01an/ preloadfmt mlf order = data; 
      var flag;
      output n = bign nmiss = nmiss out = BigN; 
    run;
    
    data _null_;
      set BigN;
      call symputx("N_"||strip(trt01an), put(bign,best.)); 
    run;
    
    data check_bign;
      set sashelp.vmacro;
      where index(name, "N_") and length(name)<=6;
      keep name value; 
    run;
    
    **3.2 Calculate small n and percentage;
    
    *Get small n;
    proc means data = adae nway completetypes;
      format trt01an trt01an.;
      class trt01an/ preloadfmt mlf order = data;
    
      class cat;
    
      var flag;
      output n = count nmiss = nmiss out = count1; 
    run;
    
    *Get percentage; 
    data count2;
      merge count1 bign; 
      by trt01an;
      length freq $200;
      if bign ne 0 then freq = strip(put(count,best.))||" ("||strip(put(count/bigN*100,8.1)) ||")";
      else freq = "0 (-)";
    
      proc sort;
        by cat trt01an;
    run;
    
    *Transpose results;
    proc transpose data = count2 out = count3 prefix= trt_ ;
      by cat; 
      var freq; 
      id trt01an; 
    run;
    
    *Create group vars;
    data final1;
      set count3;
    
      length c1 - c4 $200;
    
      if index(cat, "01")  then c1 = scan(cat, 2, "!");
      else if index(cat, "02") and count(cat, "!") = 1 then c1 = scan(cat, 2, "!");
      else if index(cat, "02") and count(cat, "!") = 2 then c1 = scan(cat, 3, "!");
    
      c2 = trt_450;
      c3 = trt_451;
      c4 = trt_999;
    
      *For freqency sort;
      num = input(scan(c4,1,"("), best.);
    
      cat1 = scan(cat, 2, "!");
      cat2 = scan(cat, 3, "!");
    
      if index(cat, "01") then call missing(of cat1-cat2);
      
      keep num c:;
    
      proc sort;
        by cat1 cat2;
    run;
    
    *Get counts for the group vars;
    data final2;
      set final1;
      by cat1 cat2;
    
      retain cat1n cat2n;
    
      if first.cat1 then cat1n = num;
      if first.cat2 then cat2n = num;
    
      proc sort;
        by descending cat1n cat1 descending cat2n cat2;
    run;
    
    
    ***4. Create dataset for QC;
    略
    
    ***5. Compare;
    略
    

    总结

    文章介绍了使用层级拼接法输出AE SOC和PT受试者发生率的汇总表格,这个方法的效率比单独计算表格各部分再统一汇总输出高很多。

    关于层级拼接的处理、频数降序排序的处理,大家可以结合代码和输出结果,进行理解。

    可以结合文章SAS编程-Table:层级关系的频数汇总处理 ——层级拼接法进一步理解这个方法,推荐大家尝试使用。

    感谢阅读, 欢迎关注!
    若有疑问,欢迎评论交流!

    相关文章

      网友评论

        本文标题:SAS编程-Table:层级拼接法输出AE SOC、PT的受试者

        本文链接:https://www.haomeiwen.com/subject/yozvyrtx.html