“ACROSS” in PROC REPORT

advertisement
NESUG 16
Pharmaceuticals
“ACROSS” in PROC REPORT
Cephalon Inc. West Chester, PA
Jiang Jin
INDEX1, INDEX2, and INDEX3 are used to adjust BODY, TERM,
and TREAT in sequential order. There are not any patient in the
BODY1, TERM1, and DOSE2 rows as well as some other
categories. These cells are represented by " 0 " in the summary
table.
ABSTRACT
The PROC REPORT has been known as one of the most
powerful and user friendly procedures in clinical trial study
summary table writing.
According to the SAS user manual, columns covered by across
variables contain only numeric variables. The preferable
alternative of selecting ACROSS usage in the DEFINE statement
in PROC REPORT has not been practiced by many SAS users.
Min Fu introduced a new method to use ACROSS to cover
character variables in "Using ACROSS Variable in PROC
REPORT PROCEDURE" on NESUG'96 Proceedings.
Following the suggestions as documented in Min Fu' coding
examples, this paper provides the answer to many detailed
problems in using ACROSS usage and makes it a practical
approach in clinical summary tables writing.
The author assumes all readers of this paper have prior
experience using PROC REPORT.
The common algorithm to create the shown summary table with
the data set listed above is using PROC TRANSPOSE to generate
a new data set (which splits VALUE into 4 treatment columns)
and then performing PROC REPORT to produce the table.
One issue related to the PROC TRANSPOSE for this case is: if a
similar table with only one study dose(PLACEBO and DOSE1) is
requested, the program has to be modified to specifically match
the number of columns. This issue could cause extra coding
work when a generic report macro is required.
In the next section questions related to selecting ACROSS usage
in the DEFINE statement in PROC REPORT and using the given
data set in PROC REPORT directly are discussed. The coding
procedure in the example could serve as a practical approach of
generating clinical trial summary tables using ACROSS usage.
INTRODUCTION
A common layout of the clinical trial summary table is:
USING ACROSS:
As introduced in Min Fu's paper, the first step is adding a dummy
variable dummy=1 in the given data set. Then submit the
following program:
----------- TREATMENT GROUP-------BODY
BBODY
PREFERRED
SYSTEM
MSYSTEM TERM
PLACEBO
DOSE1
DOSE2
TOTAL
( N=88 )
( N=87 )
( N=68 )
( N=263 )
------------------------------------------------------------------------------------------------------------TOTAL
T TOTAL
BODY1
B BODY1 TOTAL
BODY2
20 ( 22.7% )
18 ( 20.7% )
12 ( 17.7% )
8 ( 9.1% )
8 ( 9.2 % )
6 ( 8.8% )
TERM1
5 ( 5.7% )
6 ( 6.9% )
0
.
11 ( 4.2% )
TERM2
6 ( 6.8% )
0
.
4 ( 5.9% )
10 ( 3.8% )
TERM3
3 ( 3.4% )
2 ( 2.3% )
2 ( 2.9% )
7 ( 2.7% )
B BODY2 TOTAL
8 ( 9.1% )
TERM1
0
TERM2
TERM3
.
8 ( 9.2 % )
6 ( 8.8% )
proc report data=sample2 nowd headline headskip spacing=4
split="\";
col body term treat, (value) dummy;
define body / group order=data "BODY \ SYSTEM" width=8 left;
define term / group order=data "PREFERRED \ TERM" width=14
left;
define treat / across order=data "-TREATMENT GROUP- \ " ;
define value / " " width=14;
define dummy / noprint;
break after body / skip;
run;
50 ( 20.0% )
22 ( 8.4% )
22 ( 8.4% )
6 ( 6.9% )
5 ( 7.4% )
11 ( 4.2% )
6 ( 6.8% )
0
.
4 ( 5.9% )
10 ( 3.8% )
3 ( 3.4% )
2 ( 2.3% )
2 ( 2.9% )
7 ( 2.7% )
The table is created as:
……………………………………………………….
------------------- TREATMENT GROUP-----------------BODY
BBODY
PREFERRED
SYSTEM S SYSTEM TERM
The structure of a data set(SAMPLE2) used to produce this
summary would be:
BODY INDEX2 TERM INDEX3 TREAT
VALUE
-------------------------------------------------------------------------------------TOTAL
1
1
PLACEBO
20 ( 22.7% )
TOTAL
1
2
DOSE1
18 ( 20.7% )
TOTAL
1
3
DOSE2
12 ( 17.7% )
TOTAL
1
4
TOTAL
50 ( 20.0% )
BODY1
2
TOTAL
1
PLACEBO
8 ( 9.1% )
BODY1
2
TOTAL
2
DOSE1
8 ( 9.2 % )
BODY1
2
TOTAL
3
DOSE2
6 ( 8.8% )
BODY1
2
TOTAL
4
TOTAL
22 ( 8.4% )
BODY1
3
TERM1
1
PLACEBO
5 ( 5.7% )
BODY1
3
TERM1
2
DOSE1
6 ( 6.9% )
BODY1
3
TERM1
4
TOTAL
11 ( 4.2% )
BODY1
3
TERM2
1
PLACEBO
6 ( 6.8% )
BODY1
3
TERM2
3
DOSE2
4 ( 5.9% )
BODY1
3
TERM2
4
TOTAL
10 ( 3.8% )
......
PLACEBO
DOSE1
DOSE2
TOTAL
--------------------------------------------------------------------------------------------------------------TOTAL
T TOTAL
BODY1
B BODY1 TOTAL
TERM1
TERM2
6 ( 6.8% )
TERM3
3 ( 3.4% )
B BODY2 TOTAL
8 ( 9.1% )
BODY2
20 ( 22.7% )
18 ( 20.7% )
12 ( 17.7% )
8 ( 9.1% )
8 ( 9.2 % )
6 ( 8.8% )
5 ( 5.7% )
6 ( 6.9% )
TERM1
2 ( 2.3% )
8 ( 9.2 % )
6 ( 6.9% )
TERM2
6 ( 6.8% )
TERM3
3 ( 3.4% )
2 ( 2.3% )
……………………………………
50 ( 20.0% )
22 ( 8.4% )
11 ( 4.2% )
4 ( 5.9% )
10 ( 3.8% )
2 ( 2.9% )
7 ( 2.7% )
6 ( 8.8% )
22 ( 8.4% )
5 ( 7.4% )
11 ( 4.2% )
4 ( 5.9% )
10 ( 3.8% )
2 ( 2.9% )
7 ( 2.7% )
NESUG 16
Pharmaceuticals
Compared with the required table in the introduction section,
three problems need to be solved.
#1. header "---TREATMENT GROUP -----" should only cover
PLACE, DOSE1, and DOSE2
columns but not TOTAL column.
#2. numbers of patient (N= ) in each group are missing.
#3. "0
" is required to fill null cells in the table.
-----TREATMENT GROUP-----BODY
PPPREFERRED
SYSTEM
PLACEBO
DOSE1
DOSE2
TOTAL
( N= 88 )
( N=87 )
( N=68 )
( N=263 )
M TERM
-------------------------------------------------------------------------------------------
ANSWER TO PROBLEM #1.
To shift "TREATMENT GROUP" in order not to cover TOTAL
column, perform
data _null_;
call symput("header", "--TREATMENT GROUP-10));
run;
" || repeat(byte(9),
Format $trt is used to add number of patients in each treatment
group and the total group in the header.
Note: byte(9) is for PC SAS, byte(160) is for SAS on UNIX or
other large system.
ANSWER TO PROBLEM #3.
proc report data=sample2 nowd headline headskip spacing=4 split="\";
col body term treat, (value) dummy;
define body / group order=data "BODY \ SYSTEM" width=8 left;
define term / group order=data "PREFERRED \ TERM" width=14 left;
define treat / across order=data "&header \ " ;
define value / " " width=14;
define dummy / noprint;
break after body / skip;
run;
proc format;
value $value
""=" 0
"
;
run;
proc report data=sample2 nowd headline headskip spacing=4
split="\";
col body term treat, (value) dummy;
define body / group order=data "BODY \ SYSTEM" width=8 left;
define term / group order=data "PREFERRED \ TERM" width=14
left;
define treat / across order=data "&header \ " format=$trt.;
define value / " " format=$value. width=14;
define dummy / noprint;
break after body / skip;
run;
table with header shifted to the left can be produced.
-----TREATMENT GROUP----BODY
P
PREFERRED
PLACEBO
DOSE1
DOSE2
TOTAL
SYSTEM TE TERM
---------------------------------------------------------------------------
Format $value is added to change null cell in the table to " 0
".
CONCLUSION:
&header is used to shift the TREATMENT GROUP header to not
cover TOTAL column.
The technique of using ACROSS usage in the DEFINE statement
in PROC REPORT is presented in this paper. Also, the methods
of shifting header, adding number of patients under each
treatment column, and changing null cells to " 0 " are
introduced by coding example. Practicing the algorithm
introduced by this paper could save SAS users' coding time and
avoid potential mistakes caused by PROC TRANSPOSE.
ANSWER TO PROBLEM #2.
To add number of patients (N) under each treatment and total
column, the following block of code can be added to generate
format $trt.
proc sql;
create table fmts as
select '$trt' as fmtname , treat
as start ,
trim(treat) || '\(N=' || put(count(distinct patno),3.) || ')'
as
label length=20
from sample1 group by index3, treat;
proc format cntlin=sfmt; quit;
Note: SAMPLE1 is the original data set used to generate
SAMPLE2.
With macro variable &header and format $trt,
REFERENCES
SAS Institute, Inc., SAS Technical Report P-222, Changes and
Enhancements to Base SAS Software, Release 6.07, Cary, NC.
SAS Guide to the SQL Procedure, Usage and Reference,
Version 6, First Edition.
SAS is a registered trademark or trademark of SAS Institute Inc.
in the USA and other countries. â indicates USA registration.
proc report data=sample2 nowd headline headskip spacing=4
split="\";
col body term treat, (value) dummy;
define body / group order=data "BODY \ SYSTEM" width=8 left;
define term / group order=data "PREFERRED \ TERM" width=14
left;
define treat / across order=data "&header \ " format=$trt.;
define value / " " width=14;
define dummy / noprint;
break after body / skip;
run;
ACKNOWLEDGMENTS
I would like to thank Vincent Rabatin for his input and
assistance.
CONTACT INFORMATION
Email: jjin@cephalon.com
generates the table below with the following header.
2
Download