Showing posts with label safety reporting. Show all posts
Showing posts with label safety reporting. Show all posts

Friday, May 11, 2012

Adverse Event Tables (Continued)

I stated in my previous post that I would share a few more examples on how to use the AESUM macro.  Well, I like to keep my promises, so here we go...


To review, I am taking this data from Jack Shostack's book SAS Programming in the Pharmaceutical Industry.  The data can be found here.  (Scroll down to Program 5.4.)



/***  INPUT SAMPLE TREATMENT DATA  ***/
data treat;
label subjid = "Subject Number"
      trtcd  = "Treatment";     
input subjid trtcd @@;
datalines;
101 1  102 0  103 0  104 1  105 0  106 0  107 1  108 1  109 0  110 1
111 0  112 0  113 0  114 1  115 0  116 1  117 0  118 1  119 1  120 1
121 1  122 0  123 1  124 0  125 1  126 1  127 0  128 1  129 1  130 1
131 1  132 0  133 1  134 0  135 1  136 1  137 0  138 1  139 1  140 1
141 1  142 0  143 1  144 0  145 1  146 1  147 0  148 1  149 1  150 1
151 1  152 0  153 1  154 0  155 1  156 1  157 0  158 1  159 1  160 1
161 1  162 0  163 1  164 0  165 1  166 1  167 0  168 1  169 1  170 1
;
run;

/***  INPUT SAMPLE ADVERSE EVENT DATA  ***/
data ae;
label subjid   = "Subject Number"
      aebodsys = "Body System of Event"
      aedecod  = "Preferred Term for Event"
      aerel    = "Relatedness: 1=not,2=possibly,3=probably"
      aesev    = "Severity/Intensity:1=mild,2=moderate,3=severe";     
input subjid 1-3 aerel 5 aesev 7 aebodsys $ 9-34 aedecod $ 38-62;
datalines;
101 1 1 Cardiac disorders            Atrial flutter
101 2 1 Gastrointestinal disorders   Constipation
102 2 2 Cardiac disorders            Cardiac failure
102 1 1 Psychiatric disorders        Delirium
103 1 1 Cardiac disorders            Palpitations
103 1 2 Cardiac disorders            Palpitations
103 2 2 Cardiac disorders            Tachycardia
115 3 2 Gastrointestinal disorders   Abdominal pain
115 3 1 Gastrointestinal disorders   Anal ulcer
116 2 1 Gastrointestinal disorders   Constipation
117 2 2 Gastrointestinal disorders   Dyspepsia
118 3 3 Gastrointestinal disorders   Flatulence
119 1 3 Gastrointestinal disorders   Hiatus hernia
130 1 1 Nervous system disorders     Convulsion
131 2 2 Nervous system disorders     Dizziness
132 1 1 Nervous system disorders     Essential tremor
135 1 3 Psychiatric disorders        Confusional state
140 1 1 Psychiatric disorders        Delirium
140 2 1 Psychiatric disorders        Sleep disorder
141 1 3 Cardiac disorders            Palpitations
;
run;


Although the macro requires two separate datasets, I am going to merge the two because I need the treatment group variable in the AEDSN dataset for grouping in the BYVAR parameter.  But I still need both datasets for the macro input.

data ae;
      merge ae treat;
      by subjid;
run;


/***  Call the AESUM macro  ***/
/***  (remember to either call the full code from your SAS editor or to save it in a separate file as I did below)  ***/
%inc 'D:\Documents and Settings\dbateman\Desktop\Reusable Macros\AE Summary Macro.sas';

/***  I added the BYVAR parameter to group by TRTCD  ***/
/***  I added the WHR parameter to select only drug-related AEs  ***/
/***  I changed the DISPLAYSOC parameter to N  ***/
%aesum(aedsn=ae, whr=%str(aerel in (2,3)), safdsn=treat, byvar=trtcd, grdvar=aesev, soc=aebodsys, pref=aedecod, subjid=subjid, minpercent=-1, outdsn=aesum, displaysoc=N);

After running the AESUM macro, this is what the OUTDSN table holds:



With the data in this form, there are a couple of things you can do:
  1. You can run two separate outputs and 
    • only output any by0_ variables for the control group
    • only output any by1_ variables for the treatment group
  2. You can run a single output with just the _grd0 (all grades combined) variables or just the Grade 3-4, or whatever you desire as your situation allows
I will do both, just for fun.




SAS Code 1


options formchar="|____|+|___+=|_/\<>*" pageno=1 nonumber nodate orientation=portrait center;
ods listing close;
ods rtf file="D:\Documents and Settings\dbateman\Desktop\AE Table.rtf" style=journal;
ods escapechar='~';

%let user=%sysfunc(upcase(&sysuserid.));
%let proddt=%sysfunc(date(),worddate.);

title1 j=left font='Arial' 'ABC Company, Inc.' j=right "Page ~{pageof}";
title2 j=left font='Arial' "Protocol: AZ1234";
footnote1 j=left font='Arial' "Program: AE_Example.sas by &user." j=right "Date Produced: &proddt.";
proc report data=aesum nowindows split='^' style(column)={asis=on}
            style(report)={font=('Arial',9.5pt,bold italic) pretext="Drug-Related Treatment Emergent Adverse Events \line\ (Control Group)"};
      column header by0_grd0 by0_grd1 by0_grd2 by0_grd3 aedecod;
      define header / display left 'System Organ Class/^Preferred Term' style=[CellWidth=30%];
      define by0_grd0 / display center 'All Grades^n (%)' style=[CellWidth=10%];
      define by0_grd1 / display center 'Mild^n (%)' style=[CellWidth=10%];
      define by0_grd2 / display center 'Moderate^n (%)' style=[CellWidth=10%];
      define by0_grd3 / display center 'Severe^n (%)' style=[CellWidth=10%];
      define aedecod / noprint;  /*  Must include this in order to identify correct rows to bold in next step  */
      compute aedecod;
        if aedecod=' ' then do/*  If system organ class is listed, then bold that row  */
           call define(_row_, "style", "style=[font_weight=bold]");
        end;
      endcomp;
run;

proc report data=aesum nowindows split='^' style(column)={asis=on}
            style(report)={font=('Arial',9.5pt,bold italic) pretext="Drug-Related Treatment Emergent Adverse Events \line\ (Treatment Group)"};
      column header by1_grd0 by1_grd1 by1_grd2 by1_grd3 aedecod;
      define header / display left 'System Organ Class/^Preferred Term' style=[CellWidth=30%];
      define by1_grd0 / display center 'All Grades^n (%)' style=[CellWidth=10%];
      define by1_grd1 / display center 'Mild^n (%)' style=[CellWidth=10%];
      define by1_grd2 / display center 'Moderate^n (%)' style=[CellWidth=10%];
      define by1_grd3 / display center 'Severe^n (%)' style=[CellWidth=10%];
      define aedecod / noprint;  /*  Must include this in order to identify correct rows to bold in next step  */
      compute aedecod;
        if aedecod=' ' then do/*  If system organ class is listed, then bold that row  */
           call define(_row_, "style", "style=[font_weight=bold]");
        end;
      endcomp;
run;

ods rtf close;
ods listing;
title; footnote;


Output 1






SAS Code 2


options formchar="|____|+|___+=|_/\<>*" pageno=1 nonumber nodate orientation=portrait center;
ods listing close;
ods rtf file="D:\Documents and Settings\dbateman\Desktop\AE Table.rtf" style=journal;
ods escapechar='~';

%let user=%sysfunc(upcase(&sysuserid.));
%let proddt=%sysfunc(date(),worddate.);

title1 j=left font='Arial' 'ABC Company, Inc.' j=right "Page ~{pageof}";
title2 j=left font='Arial' "Protocol: AZ1234";
footnote1 j=left font='Arial' "Program: AE_Example.sas by &user." j=right "Date Produced: &proddt.";
proc report data=aesum nowindows split='^' style(column)={asis=on}
            style(report)={font=('Arial',9.5pt,bold italic) pretext="Drug-Related Treatment Emergent Adverse Events \line\ (By Treatment Group)"};
      column header by0_grd0 by1_grd0 aedecod;
      define header / display left 'System Organ Class/^Preferred Term' style=[CellWidth=30%];
      define by0_grd0 / display center 'Control Group^n (%)' style=[CellWidth=10%];
      define by1_grd0 / display center 'Treatment Group^n (%)' style=[CellWidth=10%];
      define aedecod / noprint;  /*  Must include this in order to identify correct rows to bold in next step  */
      compute aedecod;
        if aedecod=' ' then do;  /*  If system organ class is listed, then bold that row  */
           call define(_row_, "style""style=[font_weight=bold]");
        end;
      endcomp;
run;

ods rtf close;
ods listing;
titlefootnote;


Output 2

You can see that this output simply takes the first column ("All Grades") from each of the two outputs above and merges them together:




There are many more options with this macro.  Take time to play around with it and see how it can fit your needs.  And, please, if you find any errors in this macro as you go along, leave me a comment so I can continue to make this macro more user friendly!