Using Across Variable in PROC REPORT Procedure

Coders' Corner
USING ACROSS VARIABLE IN PROC REPORT PROCEDURE
Min Fu, Trilogy Consulting Corp.
ABSTRACT
When using PRoe REPORT, one can define a set of
nested across variables. This is a useful feature when
values of a group variable need to be printed on top of
values of an another group (subgroup) variable and the
values of both variables need to be presented horizontally
rather than vertically to span multiple columns of
summary and statistics in report tables (see Case 1). In
order to use the across variable feature, one usually
defines a numeric analysis variable above or below an
across variable. If one or more character variables are to
be reported and placed below an across variable and no
numeric variable is defmed, the procedure stops because
it is not able to calculate statistics on character variables
crossed by the across variable. One way to get around
this difficulty involves playing tricks in both the data step
and the PROe REPORT procedure (see Case 2).
values being placed on top of GENDER and RACE and
the values of GENDER and RACE being placed on top of
AES. All of their values are presented horizontally while
the values of BODYSYS and eOSTART are presented
vertically. The following SAS code provides a table with
the specified layout.
proc report data=CASE1. nowindows spacing=o;
=1umn BODYSYS COSTART TREAT, (GENDER, (ABS)
RACE, (ABS) ) ;
define
define
define
define
define
define
BODYSYS
COSTART
TRE1\.T
GENDER
RACE
J\ES
rbreak after
/
/
/
/
/
/
group 'Body System' \ --' ,.
group 'COSTART Term' '--' ,.
across '--';
across '--';
across '--';
n '--';
/ sumtarize 01;
nm;
CASE I
Often in clinical research, a summary table of adverse
events is reported by treatment group (drug andlor
therapy) and demographic group (age, gender andlor
race), as well as by body system and COSTART* term.
People who review such summary tables often ask for a
layout format in which values of treatment and
demographic group are presented horizontally rather than
vertically. One can use the PROC REPORT procedure to
produce tables with this kind of layout by defining a set
of across variables that include treatment and
demographic group. Here is an example.
Suppose a data set contains variables TREAT, GENDER,
RACE, BODYSYS, COSTART and AES, where TREAT
is a variable whose values represent different therapies or
drugs; GENDER variable has values Male and Female;
RACE variable has three values, White, Black and Other;
BODYSYS and COSTART have multiple values; and
AES is an indicator variable whose value is either true or
missing depending on whether a subject reported an
adverse event. GENDER and RACE are subgroup
variables of TREAT while eOSTART is a subgroup
variable of BODYSYS. The layout requires TREAT
The Coding Symbol for a Thesaurus of
Adverse Reaction Terms.
In the above code, variables TREAT, GENDER and
RACE are defined as across variables while AES is
defined as an analysis variable reported on statistical
counts for eOSTART under BODYSYS by TREAT,
GENDER and RACE. In order for the across variable
feature to function, AES must be a numeric variable while
the other variables may be either numeric or character.
CASE 2
Unless an across variable is also an analysis variable on
which the counts by other group variables need to be
reported, at least one numeric variable has to be defmed
as an analysis variable (such as AES in Case I) in order
for the across variable feature to function. In practice,
values of numeric variables are often converted to
character values so that they can be presented in better
formats. The table on the next page often appears in
clinical study reports. 'Treat I', 'Treat 2', 'Treat 3' and
'Total' are the values of a treatment group variable which
are to be presented horizontally. To display symbols '%'
and '0' together with the report variable values, these
variables must be character. One has to use some
ingenuity to make the across variable feature function
when no numeric report variable need to be shown on a
table.
223
NESUG '96 Proceedings
Coders' Corner
In the above code, FOOLRPT, a numeric variable with a
uniform value (such as I or any other value) for all
observations, was included in data set CASE2. In the
PROC REPORT procedure, this variable was defined as
an analysis variable below the across variable TREAT
and the two character variables STATl and STAT2,
which are primary report variables. Thus, the PROC
REPORT procedure crosses TREAT values over STATl
and STAT2, and also prints out the values of FOOLRPT.
In order to avoid having the values of FOOLRPT
presented in the table, the global column width in the
report was set to zero (colwidth=O in PROC REPORT
options), and the format of FOOLRPT was defined as 0.,
since the procedure prints formatted values by default.
The result is that the values of STA Tl and STAT2 appear
in the table crossed by values of TREAT while the values
of FOOLRPT are not presented.
The following code was used to produce the table below
in a practical clinical study.
proc report data=CASE2 colw.i..dth:O missing
headskip headline nowindwos;
column GROUP SUBGROOP TREAT, (STIcrl. STI\.T2)
FOOIiRP'r;
define GROUP
/ group order=data ' ';
define S1JB3ROOP / group order=freq , ,
spacing=O;
define TREAT
/ across order=data ' ';
define STIcrl.
/ spacing=2 widt:h=8'
N' ;
define STAT2
/ spacing=l widt:h=7'
%' ;
define FOOIiRP'r / fcmDaboO. spaeing::O ' ';
break after GROUP / skip;
after;
line @5 120*'-';
endcatp;
catpUte
By combining the tips in Case I and Case 2, one can use
PROC REPORT as an alternative other than data _null_
and put statement to provide some sophisticated table
layouts.
=;
Treat 1
N
Treat 2
N
Treat 3
Total
N
N
------------------------------------------------------------.--------------.--------------------
NUMBER
75
SEX:
MALE
FEMALE
48
27
64%
36%
45
26
63%37%-
46
26
64%
36%
139
79
64%36%-
RACE:
NON-BLACK
CAUCASIAN
ORIENTAL
HISPANIC
BLACK
51
33
3
15
24
6st
44%"
4%"
20"
32%
50
36
1
13
21
70t
5H
U
1st
30t
54
35
4
15
18
75t
49%6"
2U
25t
155
104
8
43
63
7H
48t
4t
20%
29%
SMOKING HISTORY:
~Y SMOKING
NOT CURRENTLY SMOKING
16
59
21%
79%
9
62
13%
87t
12
60
171<
83%
37
181
17%
83t
50
25
67%
33%
50
21
70%
30t
54
18
75t
25t
154
64
7lt
29t
218
72
71
AGE (YEARS)
21-59
GE 60
MEAN (SE)
RANGE
53.3
( 31.0,
(
HEIGHT (IN)
MEAN (SE)
RANGE
67.3
( 59.1,
(
WEIGHT
1.3)
77.0)
54.6
( 33.0,
(
0.5)
75.2)
67.6
(
( 55.1,
1.1)
80.0)
53.0
( 26.0,
(
1.2)
72.0)
53.6
( 26.0,
( 0.7)
0.5)
76.0)
67.4
( 55.9,
( 0.5)
67.4
( 55.1,
(
75.2)
80.0)
0.3)
76.0)
(LB)
MEAN
(SE)
RANGE
186.1
(113.1"
( 4.3)
261.9)
( 5.7)
201.6
(104.9, 339.1)
( 4.6)
189.8
(108.9, 272.0)
( 2.8)
192.4
(104.9, 339.1)
---------------------------------------------------------------------------------------------------
NESUG '96 Proceedings
224
Coders' Corner
POSmONAL PARAMETERS VS. KEYWORD PARAMETERS
Michael Keohan, E-Z Solutions, Inc
There are two distinct ways of passing parameters to macros
using KEYWORD or POSITIONAL parameters. Lets first
look at the positional parameters. The positional parameters
are called positional parameters because the values you pass
are assigned strictly by the position in the macro call.
required. All that is needed is to reference the time
keyword. In fact, this is not needed either because the
default will use the automatic macro variable SYSTIME.
Here is a simple macro example:
%macro titles(num,userid,text,date,time);
title&num "Userid: &userid &text Date: &date Time:
&time";
%mend titles;
%titles(l, MK998, Example of Passing Macro Parameters,
3IDEC99.11:59)
The macro statement resolves to
title 1 "Userid: MK998 example of Passing Macro
Parameters Date: 3IDEC99 Time: 11 :59";
An advantage to this approach is it will allow you to create
global macro variables which could then be referenced
outside the macro definition. This can be advantageous if
you are designing a macro based system and you want to
limit the number of macro variables you are creating.
The keyword parameter calls has several advantages over its
positional counterpart. FITSt, you can define defaults within
the macro definition as follows:
%macro titles (num=I, userid=TMK998, text=,
date=&sysdate. time=&systime);
title&num "Userid: &userid &text Date: &date Time:
&time";
%mend titles;
%titles (num=l. userid=MK998. text=Exarnple of passing
Macro Parameters, date:31DEC99, time= 11:59)
The order of the keywords referenced in the macro call
doesn't matter. Furthermore, you do not have to reference
any or all of the keyword parameters at invocation.
%titles(text=I am only assigning two keywords. time=11 :58)
Utilizing the keyword approach allows the programmer the
ability to "self document" the parameter by appropriately
naming the keyword. For instance, in the second example.
the knowledge that time is the fifth parameter is not
225
NESUG '96 Proceedings