16.4.08

Different ODS Footers

If suppose we have ten observations and we are required to present the output such that the observation are distributed on different pages depending on the value of the variable “order”. Also the different pages need to have different footers , footers being presented in the body of the document.As a first step, a variable "page" is created which represents the page number corresponding to the observation in the dataset as described below.

data catval1;
set catval end=eof;
if order le 4 then page=1;
else if 5 le order le 7 then page=2;
else if order ge 8 then page=3;
run;

The footers can be presented in the body of the document using compute before /after statements in proc report as below.

proc report data= catval1 ;
column order var1 var2 ;
………………………………
………………………………
Other SAS statements;
…………………………………
………………………………..
compute before page;
If page=1 then footer= "\li75 @ Subjects who select more than one race” ;
If page=2 then footer=" ";
If page=3 then footer="\li75 + BMI = Weight (kg) / [Height (m)]^2";
endcomp;

/*here _page_ is the SAS generated variable */

compute after _page_ / style=[just=l protectspecialchars=off];
footer11= footer;
footer12="\li75 # Overall p-value for continuous variables “
footer13="\li for Categorical variables from CMH general association test";
line @1 footer11 $300.;
line @1 footer12 $300.;
line @1 footer13 $300.;
endcomp;

/* this will give different footers in each page*/
by page;
run;

The first page will contain the following footers

@ Subjects who select more than one race
# Overall p-value for continuous variables
for Categorical variables from CMH general association test

The second page will contain the following footers

# Overall p-value for continuous variables
for Categorical variables from CMH general association test

The third page will contain the following footers
+ BMI = Weight (kg) / [Height (m)]^2
# Overall p-value for continuous variables
for Categorical variables from CMH general association test

NOTE: Groups are not created because the usage of parameter is DISPLAY.

A SAS dataset named subject is created. The SAS code for the creation of the dataset subject is as follows:
data subject;
input patid name$ sex$ visit $ parameter$ result $;
cards;
0101 lisha f Screening weight 65
0101 lisha f Screening height 150
0101 lisha f Visit1 weight 66
0101 lisha f Visit1 height 150
0102 manu m Screening weight 80
0102 manu m Screening height 165
0102 manu m Visit1 weight 80
0102 manu m Visit2 height 165
;
run;

The aim is to summarize the values across a single observation. The template is as follows:

When using the following code, the output is generated but a Note is also generated in the log as mentioned below:

proc report data=subject nowindows;
column patid name sex visit parameter result;
define patid/"Patient Number" group;
define name/"Subject Number" group;
define sex/"Sex" group;
define visit/"Visit" group;
define parameter/"Test" display;
define result/"Values" display;
run;

The SAS log will look like as follows::
1
2
3 data subject;
4 input patid name$ sex$ visit $ parameter$ result $;
5 cards;
NOTE: The data set WORK.SUBJECT has 8 observations and 6 variables.
NOTE: DATA statement used:
real time 0.01 seconds
cpu time 0.00 seconds
14 ;
15 run;
16
17 proc report data=subject nowindows;
18 column patid name sex visit parameter result;
19 define patid/"Patient Number" group;
20 define name/"Subject Number" group;
21 define sex/"Sex" group;
22 define visit/"Visit" group;
23 define parameter/"Test" display;
24 define result/"Values" display;
25 run;
NOTE: Groups are not created because the usage of parameter is DISPLAY.
NOTE: There were 8 observations read from the data set WORK.SUBJECT.
NOTE: PROCEDURE REPORT used:
real time 0.01 seconds
cpu time 0.01 seconds

A note is produced in the SAS log “NOTE: Groups are not created because the usage of parameter is DISPLAY.”
To remove this note from the log the following code should be used.

proc report data=subject nowindows;
column patid name sex visit parameter result;
define patid/"Patient Number" order;
define name/"Subject Number" order;
define sex/"Sex" order;
define visit/"Visit" order;
define parameter/"Test" display;
define result/"Values" display;
run;

The log is generated as
1
2
3 data subject;
4 input patid name$ sex$ visit $ parameter$ result $;
5 cards;
NOTE: The data set WORK.SUBJECT has 8 observations and 6 variables.
NOTE: DATA statement used:
real time 0.00 seconds
cpu time 0.00 seconds
14 ;
15 run;
16
17 proc report data=subject nowindows;
18 column patid name sex visit parameter result;
19 define patid/"Patient Number" order;
20 define name/"Subject Number" order;
21 define sex/"Sex" order;
22 define visit/"Visit" order;
23 define parameter/"Test" display;
24 define result/"Values" display;
25 run;
NOTE: There were 8 observations read from the data set WORK.SUBJECT.
NOTE: PROCEDURE REPORT used:
real time 0.00 seconds
cpu time 0.00 seconds


The SAS log is now free of the notes, errors and warnings. Instead of using the group variable, use order with display in the define statement.
Applying Cochran-Mantel–Haenzel (CMH) general association test

Compiled by Rupesh R

Here the objective is to determine the general association between categorical variables subject and ranking for each emotion.

The CMH general association test is applied for this purpose. Proc freq is as described below to carry out the test. Proc freq generates p-values corresponding to each emotion and the results are outputted to the dataset hypnosis1.


The dataset is created as follows


data hypnosis;
input subject emotion $ ranking @@;
cards;
1 fear 4 1 joy 3 1 sadness 1 1 calmness 2
2 fear 4 2 joy 2 2 sadness 3 2 calmness 1
3 fear 3 3 joy 2 3 sadness 4 3 calmness 1
4 fear 4 4 joy 1 4 sadness 2 4 calmness 3
5 fear 1 5 joy 4 5 sadness 3 5 calmness 2
6 fear 4 6 joy 3 6 sadness 2 6 calmness 1
7 joy 4 7 joy 1 7 sadness 2 7 calmness 3
8 joy 3 8 joy 4 8 sadness 2 8 calmness 1
;
run;


The following code is used to carry out the analysis. The option ‘cmh’ in the ‘tables’ statement carries out the test. The option ‘cmhga’ presents the P-value for CMH General Association without a warning in the log.


proc sort;
by emotion;
run;



proc freq;
tables subject*ranking / cmh;
by emotion;
output out=hypnosis1 cmhga;
run;


The dataset hypnosis1 is obtained as follows





























emotion_CMHGA_DF_CMHGAP_CMHGA
calmness14140.449711056
fear10100.440493285
joy20.25210.505479124
sadness21210.458944209


In the dataset p_cmhga will be labeled as ’ P-value for CMH General Association’; df_cmhga as “DF for CMH General Association” and _cmhga_ as “CMH General Association” .

15.4.08

Using just=dec for alignment of decimals

Compiled by Prajitha Nair

We have a column in proc report with either 1 or 2 digits right of the decimal and an uncertain number of digits to the left. For enhanced output, the values have to be presented such that they are aligned with respect to the decimal point.

When the display value contains a decimal point, we can use just=dec to align the numbers directly. The JUST=DEC option can be used to align the decimal points in the values in a column

define colname / display "Column/header" style=[just=dec];

where colname is the name of the column name as specified in the SAS.

If we are using ods rtf tags then we can use the pretext option for the purpose

define colname /display “Column Header”

style(column)={pretext="\qj\tqdec\tx1200" protectspecialchars=off just=center};

Extracting Engine and Path name of the code
Compiled by Prajitha Nair




The input parameter in the macro will be the name of the SAS file whose path is to be determined.

%macro PathbyName(progName);

%global fullPath fullPath1 engine;
%if %index(%upcase(&progName),.SAS) eq 0 %then
%let progName=&progName..sas;

proc sql noprint;
select xpath into :fullPath
from dictionary.extfiles where
index(upcase(xpath),"%upcase(&progName) " ) gt 0 ;
select setting into :engine from sashelp.voption
where optname="ENGINE";
quit;

%let engine = %trim(&engine);
%put engine = &engine;
%let fullpath = %trim(&fullPath);

%put fullpath = &fullPath;

%mend PathbyName;

Accessing the current working directory where the file containing the SAS code is stored


Compiled by Prajitha Nair


Let the SAS editor containing the code be KR-PH-XXX-SAS-Init.sas and it is stored in a folder named SAS Programs_Final.


The following %let statements assigns the folder and editor names to macro variables pgmfld and pgm respectively.


%let pgmfld = SAS Programs_Final; /*Folder in which SAS code is stored*/
%let pgm= KR-PH-XXX-SAS-Init.sas; /*Name of the program editor*/


The following macro is then used to extract the path of the editor from sashelp.vextfl and determine the path of the folder as “dir1” and of the editor as “dir2”.


%macro filePath;
%global fpath maxRef;

proc sql noprint;
select xpath into :fPath
from sashelp.vextfl where xpath ? "&pgm";
quit;


%let fpath = %trim(&fpath);
%put &fpath;
%global dir1 dir2 pgm1 pgmfld1;
%let pgm1 =%trim(&pgm);
%let pgmfld1= %trim(&pgmfld);


data _null_;
x=length("&fpath")-length("&pgm1");
y=length("&fpath")-length("&pgm1")-length("&pgmfld1")-1;
call symput("dir2" ,trim(substr("&fpath",1,x)));
call symput("dir1" ,trim(substr("&fpath",1,y)));
run;


%mend filePath;


This macro helps in determining the path of the code and enables the code to be executed in any computer provided the SAS code is saved within a folder and the naming conventions are followed as above.