Download How to Go from SAS® Data Sets to DATA NULL or WordPerfect Tables

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
Transcript
How to Go From SAS® Data Sets to DATA NULL or WordPerfect Tables
Anne Horney, Cooperative Studies Program Coordinating Center, Perry Point, Maryland
ABSTRACT
Clinical trials data reports often contain many tables
produced on a recurring basis, and a way is needed to
move information from SAS® procedures into publication
quality tables without spending hours transferring and
checking numbers. Combining output values from several
procedures into one table or page of a report is often
necessary. The data values/information can be calculated
using several methods such as PROC FREQ, PROC
MEANS, and DATA steps. The table can be created using
PUT statements or the data can be written to a delimited
ASCII file that can be merged into word processing or
spreadsheet packages. An example of a report table created
by both DATA _NULL_ and WordPerfect will be shown.
SAS Code:
proc means data=form1;
class treatmnt;
var age;
output out=age
n=n_age mean=m_age std=s_age;
run;
data agea; set age;
if treatmnt=' ' then treatmnt='C';
keep treatmnt n_age m_age s_age;
run;
proc sort; by treatmnt;
run;
N AND PERCENT
USING ARRAYS IN A DATA STEP
INTRODUCTION
The goal is to produce a table that describes a continuous
variable (Age) and two categorical variables (Gender and
Marital Status) by treatment group. As is so often the case
in SAS programming, there is more than one way to
accomplish the task. SAS procedures and DATA step
programming will be used to show some ways to meet the
goal. Statistics for the continuous variable will be n, mean,
standard deviation and the probability of no difference
between treatment groups; for the discrete variables
statistics will be n, percent-of-group, and probability of no
difference between groups.
Our sample data set form1 contains five variables:
Id
Subject identifier
Treatmnt
Treatment A or B
Age
Subject's age in years
Gender
1=male, 2=female
MarStat
1=never married, 2=married,
3=divorced/widowed
The 51 observations have been sorted by treatment group;
none of the data are missing. Assume the formats
gender. and marital. exist.
STEP ONE - CALCULATING THE STATISTICS
N, MEAN, AND STANDARD DEVIATION
USING PROC MEANS
One method of calculating statistics such as means and
standard deviations is to use the procedure PROC MEANS,
which can create an output data set containing the
calculated values. The output data set is named in the
OUTPUT statement; the desired statistics are requested and
named. When the CLASS statement is used, the data set
contains statistics for each value of the class variable (here,
treatmnt) and for the total sample. The data step AGEA
changes the value of treatmnt for the total sample from ' '
(missing) to 'C' so that the data can be sorted to put the total
last.
The number occurrences of each category of a discrete
variable and percentages are calculated in a DATA step. An
array is defined for each categorical variable of interest. The
array GEN will be used to sum the occurrences of 1(male)
and 2(female) for each treatment group and overall;
likewise, MARITAL will hold the marital status counts. For
each two-dimensional array the rows are the categories and
the columns are the treatment groups. The percentages will
be calculated later in the DATA _NULL_ step.
SAS Code:
data counts(keep=gen1-gen9 mar1-mar12);
set form1 end=eof;
*columns: Treament A, B, total;
*Rows: Male, Female, Total;
array gen{3,3} gen1-gen9;
*Rows: Nvr Married,Married,Divorced,total;
array marital{4,3} mar1-mar12;
retain gen1-gen9 mar1-mar12 0;
if treatmnt='A' then trt=1;
if treatmnt='B' then trt=2;
if gender in (1,2) then do;
gen{gender,trt}+1;
gen{gender,3}+1;
*row total;
gen{3,trt}+1;
*column total;
gen{3,3}+1;
*overall total;
end;
if 1 le marstat le 3 then do;
marital{marstat,trt}+1;
marital{marstat,3}+1; *row total;
marital{4,trt}+1;
*column tot;
marital{4,3}+1;
*overall tot;
end;
if eof then output;
run;
T-TEST P-VALUE USING ANOVA PROCEDURE
STEP TWO - PRODUCING THE TABLE
Since the TTEST procedure does not have an OUTPUT
option, the ANOVA procedure, which calculates the
equivalent probability value is used.
METHOD ONE: DATA _NULL_ AND PUT
The table is produced in a DATA _NULL_ step by bring the
pieces together and using the PUT statement to write out
the data in tabular form.
SAS Code:
proc anova data=form1 outstat=p_age;
class treatmnt;
model age=treatmnt;
run;
SAS Code:
data _null_; set agea(in=ina )
counts(in=inc);
array gen{3,3} gen1-gen9;
array marital{4,3} mar1-mar12;
retain col 0;
CHI-SQUARE PROBABILITY USING PROC FREQ
Counts and percentages, as well as chi-square probabilities,
for discrete variables can be obtained by use of the
procedure FREQ along with the procedure’s two types of
output statements. For this example only the chi-square
probabilities are be used.
file print header=h1;
*Age*;
if ina then do;
col+17;
if treatmnt='A' then put
/ @1 'Age (years)' @;
put @col n_age 2.
+2 m_age 4.1
+2 s_age 4.1 @;
end;
SAS Code:
Proc freq data=form1;
table gender*treatmnt /chisq;
output out=cgender(keep=p_pchi) chisq;
run;
proc freq data=form1;
table marstat*treatmnt /chisq;
output
out=cmarital(keep=p_pchi) chisq;
run;
if treatmnt='C' then do;
set p_age (where=(_type_='ANOVA'));
put @71 prob 5.3;
end;
if inc then do;
Demographic Information by Treatment Group
Treatment Group
A
B
Total
Demographic
Information
___________
N Mean S.D.
______________
N Mean S.D.
______________
N Mean S.D.
______________
Age (years)
25
26
51
34.7
9.1
33.9
8.5
34.3
8.7
probability
___________
0.736
N
%
__________
N
%
__________
N
%
__________
Gender
Male
Female
14
11
56.0
44.0
14
12
53.8
46.2
28
23
54.9
45.1
0.877
Marital Status
Single
Married
Divorced
7
10
8
28.0
40.0
32.0
5
9
12
19.2
34.6
46.2
12
19
20
23.5
37.3
39.2
0.558
Figure 1
probability
___________
*Gender*;
put /// @20 'N
%'
@37 'N
%'
@54 'N
%'
@68 'probability'
/ @19 '__________'
@36 '__________'
@53 '__________'
@68 '___________';
/ @1 'Gender';
do row=1 to 2;
put @3 row :gender. @;
col=2;
do rx=1 to 3;
col=col+17;
if gen{3,rx} gt 0 then
pc=gen{row,rx}/gen{3,rx} * 100;
else pc=.;
put @col gen{row,rx} 2.
+ 3 pc 5.1 @;
end;
if row=1 then do;
set cgender;
put @71 p_pchi 5.3;
end;
end;
*Marital Status*;
put // @1 'Marital Status';
do row=1 to 3;
put @3 row :marital. @;
col=2;
do rx=1 to 3;
col=col+17;
if marital{4,rx} gt 0 then
pc=marital{row,rx}/marital{4,rx}
* 100;
else pc=.;
put @col marital{row,rx} 2.
+3 pc 5.1 @;
end;
if row=1 then do;
set cmarital;
put @71 p_pchi 5.3;
end;
end;
end;
return;
h1:
title 'Demographic Information by'
'Treatment Group';
put // @33 'Treatment Group'
// @23 'A' @40 'B' @56 'Total'
/ @1 'Demographic'
/ @1 'Information'
@17 ' N Mean S.D.'
@34 ' N Mean S.D.'
@51 ' N Mean S.D.'
@68 'probability'
/ @1 '___________'
@17 '______________'
@34 '______________'
@51 '______________'
@68 '___________';
run;
METHOD TWO: WORDPERFECT
The Data And Safety Monitoring Board Reports produced by
the Cooperative Studies Program Coordinating Center
include many pages of tables. The reports are prepared
semiannually for the duration of the study. A way was
needed to move information from SAS outputs into
publication quality tables without spending hours transferring
and checking numbers and repeating the process again in
six months. We used SAS and WordPerfect to produce the
necessary report tables with a minimum of manual
intervention. Examples of report tables and of the data and
WordPerfect macros that produced them will be displayed.
INFORMATION
The first step is to determine what information is to appear
in the table. Design the table in WordPerfect as a merge
form file (see Figure 2). Decide on title lines, contents and
placement of columns and rows, and labeling. The form file
will be a combination of text and merge codes. The text
entries will remain constant. Put the merge code FIELD in
each location where text and/or numeric data will be inserted
from the merge data file. These fields are consecutively
numbered. Information can be merged into titles, and
headers and footers, as well as table cells. The merge data
file is an ASCII file created in SAS.
The macro RENUMBER can be used to number the fields.
Put the tilde symbol "~" in the document where you want a
merge field code. The macro will insert the field codes
numbered appropriately. It can also be used to renumber
the fields if the table is changed.
ASCII DELIMITED TEXT FILE
The information that will be merged into the table must be
put into an ASCII delimited text file, the data file. Entries
must be placed in the file in the same order as the field
numbers in the form file. This is done with SAS PUT
statements. The delimiters can be any characters you
choose. (WordPerfect uses a comma as the default field
delimiter and [CR][LF] as the default record delimiter.)
If you plan to use the merge command from the menu or
merge bar there must be a record delimiter after the last
record. If you plan to merge the table using a WordPerfect
macro, omit the record delimiter after the last record. For
both methods, separate multiple records with delimiters. The
example is for use with a macro.
SAS Code:
data _null_; set agea(in=ina )
counts(in=inc);
array gen{3,3} gen1-gen9;
array marital{4,3} mar1-mar12;
file 'c:\nesug01\table1.dat';
*Age*;
if ina then do;
put n_age :2. '*'
m_age :4.1 '*,'
s_age :4.1 '*'@;
if treatmnt='C' then do;
set p_age(where=(_type_='ANOVA'));
put prob :5.3 '*';
end;
end;
else put;
end;
end;
Sample data file:
25 *34.7 *9.1 *26 *33.9 *8.5 *51 *34.3 *8.7
*0.736 *
14 *56.0 *14 *53.8 *28 *54.9 *0.877 *
11 *44.0 *12 *46.2 *23 *45.1 *
7 *28.0 *5 *19.2 *12 *23.5 *0.558 *
10 *40.0 *9 *34.6 *19 *37.3 *
8 *32.0 *12 *46.2 *20 *39.2 *
if inc then do;
*Gender*;
do row=1 to 2;
do rx=1 to 3;
if gen{3,rx} gt 0 then
pc=gen{row,rx}/gen{3,rx} * 100;
else pc=.;
put gen{row,rx} :2. '*'
pc 5.1 '*' @;
end;
if row=1 then do;
set cgender;
put p_pchi :5.3 '*';
end;
else put;
end;
WORDPERFECT TABLE
The study table (see Figure 3), containing the desired
information in the desired format, is achieved by merging the
ASCII data file into the WordPerfect form file using the
WordPerfect Merge command. Whenever the study data
change, a new data file can be prepared and merged into
the form file . . . yielding a relatively quick and painless
revised study table.
*Marital Status*;
do row=1 to 3;
do rx=1 to 3;
if marital{4,rx} gt 0 then
pc=marital{row,rx}/marital{4,rx}
* 100;
else pc=.;
put marital{row,rx} :2. '*'
pc 5.1 '*' @;
end;
if row=1 then do;
set cmarital;
put p_pchi :5.3 '*';
end;
TABLE MACRO
WordPerfect macros are used to automate the merging
process. For each table a macro is written containing all the
statements required to produce the finished version of the
table from a form file and a data file. The WordPerfect
macro merges the form with the data and saves the
resulting table as a WordPerfect document.
Demographic Information by Treatment Group
Treatment Group
A
Demographic
Information
Age(years)
N
Mean
B
S.D.
N
Total
Mean
S.D.
N
Mean
FIELD(1) FIELD(2) FIELD(3) FIELD(4) FIELD(5) FIELD(6) FIELD(7)
S.D.
FIELD(8) FIELD(9)
N
%
N
%
N
%
Male
FIELD(11)
FIELD(12)
FIELD(13)
FIELD(14)
FIELD(15)
FIELD(16)
Female
FIELD(18)
FIELD(19)
FIELD(20)
FIELD(21)
FIELD(22)
FIELD(23)
Single
FIELD(24)
FIELD(25)
FIELD(26)
FIELD(27)
FIELD(28)
FIELD(29)
Married
FIELD(31)
FIELD(32)
FIELD(33)
FIELD(34)
FIELD(35)
FIELD(36)
Divorced
FIELD(37)
FIELD(38)
FIELD(39)
FIELD(40)
FIELD(41)
FIELD(42)
Probability
FIELD(10)
Gender
FIELD(17)
Marital Status
Figure 2. WordPerfect Form File
FIELD(30)
ACKNOWLEDGMENTS
REPORT MACRO
The author wishes to thank Gail Kirk for her contributions to
this paper.
Carrying this a giant step forward, a WordPerfect Report
macro, has been written to produce the final report. First the
Report macro runs each individual table macro (the
command is NEST) and creates a WordPerfect file for each
table. Next the Report macro inserts each table in the
correct order into a single large document. Also, the macro
can issue additional WordPerfect commands, such as
headers, footers, and page numbers, to bring the final
document into its desired form.
SAS is a registered trademark or trademark of SAS Institute
Inc.
.
WordPerfect is a registered trademark of Corel Corporation
Limited, in the USA and other countries.
® indicates USA registration.
CONTACT INFORMATION
CONCLUSION
Anne Horney
CSPCC (151E)
VA Medical Center
P. O. Box 1010
Perry Point, MD 21902
410-642-2411 ext. 5298
[email protected]
Using DATA step arrays and/or output data sets from SAS
procedures will require some extra programming steps. The
time is well spent, though, when you compare the
programming time to the alternative of hand-transcribing,
checking, checking again, and verifying that the correct
numbers from the appropriate SAS output listings have been
put in the correct destination slots. We prepare the study
report by running SAS programs to prepare the data files
and by playing one WordPerfect macro. Thus we have
eliminated time-consuming and error-prone repetitive
transcribing and checking.
The WordPerfect macros were written for WordPerfect
version 7. Some changes to the macros may be required
for other versions. The SAS programs were written for
Version 6.12, they will also work with version 8.
Demographic Information by Treatment Group
Treatment Group
Demographic
Information
Age(years)
A
B
Total
N
Mean
S.D.
N
Mean
S.D.
N
Mean
S.D.
Probability
25
34.7
9.1
26
33.9
8.5
51
34.3
8.7
0.736
N
%
N
%
N
%
Male
14
56.0
14
53.8
28
54.9
Female
11
44.0
12
46.2
23
45.1
Single
7
28.0
5
19.2
12
23.5
Married
10
40.0
9
34.6
19
37.3
Divorced
8
32.0
12
46.2
20
39.2
Gender
0.877
Marital Status
Figure 3. WordPerfect Table
0.558
Renumber Macro
Table Macro
//Description: RENUMBER renumber all fields
//table1
Application (A1; "WordPerfect"; Default; "US")
PosDocVeryTop
SearchString ("[MRG: FIELD]")
ReplaceString ("~")
ReplaceForward (Extended!)
PosDocVeryTop ()
ForNext(LP;1;3;1)
ForNext(num; 0; 9; 1)
PosDocTop
ReplaceConfirm(No!)
SearchString("~"+num)
ReplaceString("~")
ReplaceForward(Extended!)
ENDFOR
ENDFOR
PosDocVeryTop ()
//names of the merge form file, merge data file,
//resulting merged document
CONSTANT(
vForm: = "c:\nesug01\table1.FRM";
vData: = "c:\nesug01\table1.DAT";
vTable: = "c:\nesug01\table1.WPD")
//Data file
ImportSetFileName (vData)
ImportSetSource (ASCII!)
ImportSetDestination (MergeData!)
//Field Delimiter - macro uses * as the field delimiter
//
----- can be changed
ImportSetAsciiFieldDelimiter ("*")
//Record Delimiter - macro does not use a record
//delimiter
----- can be changed
ImportSetAsciiRecordDelimiter ("")
ASSIGN(NUM; "0")
LABEL (Begin@)
ASSIGN(NUM; NUM+1)
OnNotFound(labelb)
SearchString ("~")
//Hard returns are removed from the data file before
//merging into the form file
//if you don't want hard returns deleted from the ascii
//file - delete the text between the quotes in
//(StripChars: "[SRt][HRt]")
ImportSetAsciiStrip (StripChars: "[SRt][HRt]")
SearchNext (Extended!)
SelectMode (Off!)
MergeCode (Field!; NUM)
GO(Begin@)
LABEL(labelb)
PosDocVeryTop
SearchString ("~")
ReplaceString ("")
ReplaceForward (Extended!)
beep
PosDocVeryTop
//text strings are surrounded by ""
//
----- can be changed
ImportSetAsciiEncap (EncapsulationChar: """")
//convert data file to a merge file and copy to
//clipboard
ViewDraft ()
ImportDoImport ()
PosDocTop ()
SelectDocBottom ()
EditCopy ()
Close (No!)
//do the merge
MergeSelect (All!)
//form file name, data file source, location of merged
//document
MergeRun (FormFile!; vForm;DataFileType:
Clipboard!; OutputFileType: ToNewDoc!)
//name of the document containing the merged table
FileSave(vTable;WordPerfect_60!)
Close
Report Macro
Application (A1; "WordPerfect"; Default; "US")
PERSISTALL DEFAULTUNITS(Inches!)
VARERRCHK(OFF!)
DISPLAY(Off!)
//play macro to create table Table1
FileNew()
NEST("C:\nesug01\Table1")
//play macro to create table Table2
FileNew()
NEST("C:\nesug01\Table2")
//play macro to create table Table3
FileNew()
NEST("C:\nesug01\Table3")
//play macro to create table Table4
FileNew()
NEST("C:\nesug01\Table4")
//Assemble report
FileNew()
//insert cover sheet
FileInsert("C:\nesug01\DSMB.WPD";No!;Insert!)
PosDocBottom ()
HardPageBreak ()
//insert Table of Contents
FileInsert("C:\nesug01\DSMBCONT.WPD")
PosDocBottom ()
HardPageBreak ()
//discontinue the header that is used in the Table of
// Contents
HeaderA(Off!)
//put page numbers on bottom of pages, starting with
page 1
PageNumberPosition (Position: BottomCenter!;
Default: DontUseDefaultValues!)
PageNumberMethod(Numbers!) PageNumber(1)
//insert the table Table1 -file created by macro
// Table1
FileInsert("C:\nesug01\Table1.WPD" ;
No!;Insert!)
PosDocBottom ()
//insert the table Table2 - file created by macro
// Table2
FileInsert("C:\nesug01\ Table2.WPD";
No!;Insert!)
PosDocBottom ()
HardPageBreak ()
//insert the table Table3 - file created by macro
// Table3
FileInsert("C:\nesug01\Table3.WPD";
No!;Insert!)
PosDocBottom ()
HardPageBreak ()
//insert the table Table4 - file created by macro
// Table4
FileInsert("C:\nesug01\Table4.WPD";
No!;Insert!)