Using the SAS Output Delivery System
to Assist in Writing Final Reportsrts
Paul Catalano
April 2014
Location of examples and these slides:
~pcatae/ods
Topics
•
•
•
•
What is ODS?
ODS and output destinations
Controlling the selection and format of the output
Examples:
– HTML
– RTF to MS Word
– Printer, PS, PDF
– Excel
– PowerPoint
– Other things if we have time
What is ODS?
Three Basic Components
• Output destinations
• Table definitions
• Style definitions
Quick example using PROC FREQ with
HTML output (ex1.sas)
ex1.sas
options _last_ = anal;
ods html file='ex1.html';
proc freq;
tables age01*sex01 / nopercent;
where lab=1;
run;
ods html close;
ex1.lst
The SAS System
The FREQ Procedure
Table of age01 by sex01
age01(Age)
sex01(Sex)
Frequency|
Row Pct |
Col Pct |F
|M
|
---------+--------+--------+
<= 65
|
236 |
289 |
|
44.95 |
55.05 |
|
71.95 |
68.48 |
---------+--------+--------+
> 65
|
92 |
133 |
|
40.89 |
59.11 |
|
28.05 |
31.52 |
---------+--------+--------+
Total
328
422
Total
525
225
750
ex1.sas
options _last_ = anal;
ods html file='ex1.html';
proc freq;
tables age01*sex01 / nopercent;
where lab=1;
run;
ex1.html
ods html close;
ex1.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="Generator" content="SAS Software Version 9.2, see www.sas.com">
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-1">
<title>SAS Output</title>
<style type="text/css">
<!-.AfterCaption
{
font-family: Arial, Helvetica, sans-serif;
font-size: medium;
font-weight: bold;
font-style: normal;
color: #000000;
background-color: #E0E0E0;
padding: 0px;
border-spacing: 0px;
}
…stylesheet sections deleted for space
</STYLE>
</HEAD>
<BODY onload="startup()" onunload="shutdown()" class="Body" style=" Textalign:CENTER;">
<A NAME="IDX"> </A>
<CENTER>
<TABLE cellspacing=1 cellpadding=7 class="Table" rules=GROUPS frame=BOX style=" Textalign:CENTER;">
<thead>
<TR> <TD COLSPAN=4 class="Header" style=" Text-align:CENTER;">Table of age01 by sex01</TD></
TR>
<TR> <TD ROWSPAN=2 class="Header" style=" Text-align:CENTER; Verticalalign:BOTTOM;">age01(Age)</TD>
<TD COLSPAN=2 class="Header" style=" Text-align:CENTER; Vertical-align:BOTTOM;">sex01(Sex)</
TD>
<TD ROWSPAN=2 class="Header" style=" Text-align:RIGHT; Vertical-align:BOTTOM;">Total</TD> </
TR>
<TR> <TD class="Header" style=" Text-align:RIGHT;">F</TD>
<TD class="Header" style=" Text-align:RIGHT;">M</TD> </TR>
</thead>
<tbody>
<TR> <TD class="Header" style=" Text-align:RIGHT; Vertical-align:TOP;"><= 65</TD>
<TD style=" Vertical-align:TOP;">
236<br> 44.95<br> 71.95</TD>
<TD style=" Vertical-align:TOP;">
289<br> 55.05<br> 68.48</TD>
<TD style=" Vertical-align:TOP;">
525<br> <br> </TD> </TR>
<TR> <TD class="Header" style=" Text-align:RIGHT; Vertical-align:TOP;">> 65 </TD>
<TD style=" Vertical-align:TOP;">
92<br> 40.89<br> 28.05</TD>
<TD style=" Vertical-align:TOP;">
133<br> 59.11<br> 31.52</TD>
<TD style=" Vertical-align:TOP;">
225<br> <br> </TD></TR>
<TR> <TD class="Header" style=" Text-align:LEFT; Vertical-align:TOP;">Total
</TD>
<TD style=" Vertical-align:TOP;">
328</TD>
<TD style=" Vertical-align:TOP;">
422</TD>
<TD style=" Vertical-align:TOP;">
750</TD>
</TR>
</tbody>
</TABLE>
</CENTER>
</TD>
</TR>
</TABLE>
Table Definitions
• Each piece of output has a corresponding ODS
table definition
• Think of these as the objects of the output
that you can select and control
• More later on how to select individual objects
• Example using proc phreg and RTF output
(ex2.sas)
ex2.sas
options _last_=anal;
ods rtf file='ex2.rtf';
proc phreg;
model bdfstm*bdfs(0)= age01 sex01 adjuvant duke01 regimp01
obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
title 'DFS: Patient Chars, Stratified';
run;
ods rtf close;
ex2.lst
DFS: Patient Chars, Stratified
The PHREG Procedure
Model Information
Data Set
Dependent Variable
Censoring Variable
Censoring Value(s)
Ties Handling
USER.ANAL
bdfstm
bdfs
0
BRESLOW
Disease-Free Survival (yr)
Summary of the Number of Event and Censored Values
Stratum
bprot01
Total
Event
Censored
Percent
Censored
1
E2284
201
110
91
45.27
2
E2288
522
208
314
60.15
------------------------------------------------------------------Total
723
318
405
56.02
Convergence Status
Convergence criterion (GCONV=1E-8) satisfied.
Model Fit Statistics
Criterion
-2 LOG L
AIC
SBC
Without
Covariates
With
Covariates
3572.913
3572.913
3572.913
3519.803
3537.803
3571.661
ex2.lst
Testing Global Null Hypothesis: BETA=0
Test
Chi-Square
DF
Pr > ChiSq
53.1104
58.9535
56.9963
9
9
9
<.0001
<.0001
<.0001
Likelihood Ratio
Score
Wald
Analysis of Maximum Likelihood Estimates
Variable
DF
Parameter
Estimate
age01
sex01
adjuvant
duke01
regimp01
obstrc01
diffmod
1
1
1
1
1
1
1
0.18065
0.37563
-0.22152
0.62128
0.98665
0.21009
-0.05235
Standard
Error
0.11951
0.11626
0.17279
0.15284
0.20747
0.13121
0.18409
Chi-Square
Pr > ChiSq
2.2849
10.4388
1.6436
16.5235
22.6162
2.5639
0.0809
0.1306
0.0012
0.1998
<.0001
<.0001
0.1093
0.7761
ex2.lst
DFS: Patient Chars, Stratified
The PHREG Procedure
Analysis of Maximum Likelihood Estimates
Variable
DF
diffpoor
tum5cm
1
1
Parameter
Estimate
Standard
Error
Chi-Square
0.10048
-0.08005
0.21379
0.12170
0.2209
0.4327
Pr > ChiSq
0.6384
0.5107
Analysis of Maximum Likelihood Estimates
Variable
Hazard
Ratio
age01
sex01
adjuvant
duke01
regimp01
obstrc01
diffmod
diffpoor
tum5cm
1.198
1.456
0.801
1.861
2.682
1.234
0.949
1.106
0.923
95% Hazard Ratio
Confidence Limits
0.948
1.159
0.571
1.379
1.786
0.954
0.662
0.727
0.727
1.514
1.829
1.124
2.511
4.028
1.596
1.361
1.681
1.172
Variable Label
Age
Sex
Adjuvant Rx
Dukes Stage
Reg Implants
Obstruction
Diff = moderate
Diff = poor
Tumor Size
ex2.sas
options _last_=anal;
ods rtf file='ex2.rtf';
proc phreg;
model bdfstm*bdfs(0)= age01 sex01 adjuvant duke01 regimp01
obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
title 'DFS: Patient Chars, Stratified';
run;
ods rtf close;
ex2.rtf
DFS: Patient Chars, Stratified!
The PHREG Procedure
Model Information
Data Set
USER.ANAL
Dependent Variable bdfstm
Censoring Variable
bdfs
Censoring Value(s)
0
Ties Handling
BRESLOW
Disease-Free Survival (yr)
Summary of the Number of Event and Censored
Values
Percent
Stratum bprot01 Total Event Censored Censored
1 E2284
201
110
91
45.27
2 E2288
522
208
314
60.15
723
318
405
56.02
Total
ex2.rtf
DFS: Patient Chars, Stratified!
The PHREG Procedure
Convergence Status
Convergence criterion (GCONV=1E-8)
satisfied.
Model Fit Statistics
Without
With
Covariates Covariates
Criterion
-2 LOG L
3572.913
3519.803
AIC
3572.913
3537.803
SBC
3572.913
3571.661
Testing Global Null Hypothesis: BETA=0
Test
ex2.rtf
Chi-Square DF Pr > ChiSq
Likelihood Ratio
53.1104
9
<.0001
Score
58.9535
9
<.0001
Wald
56.9963
9
<.0001
DFS: Patient Chars, Stratified!
The PHREG Procedure"
Analysis of Maximum Likelihood Estimates
Variable
95%
Hazard
Ratio
Parameter Standard
Hazard Confidence
DF Estimate
Variable Label
Error Chi-Square Pr > ChiSq Ratio
Limits
age01
1
0.18065
0.11951
2.2849
0.1306
1.198 0.948 1.514 Age
sex01
1
0.37563
0.11626
10.4388
0.0012
1.456 1.159 1.829 Sex
adjuvant
1
-0.22152
0.17279
1.6436
0.1998
0.801 0.571 1.124 Adjuvant Rx
duke01
1
0.62128
0.15284
16.5235
<.0001
1.861 1.379 2.511 Dukes Stage
regimp01
1
0.98665
0.20747
22.6162
<.0001
2.682 1.786 4.028 Reg Implants
obstrc01
1
0.21009
0.13121
2.5639
0.1093
1.234 0.954 1.596 Obstruction
diffmod
1
-0.05235
0.18409
0.0809
0.7761
0.949 0.662 1.361 Diff = moderate
diffpoor
1
0.10048
0.21379
0.2209
0.6384
1.106 0.727 1.681 Diff = poor
tum5cm
1
-0.08005
0.12170
0.4327
0.5107
0.923 0.727 1.172 Tumor Size
Style Definitions
• Tell ODS how to display the objects
• Fonts, colors, borders, layout, etc.
• Use PROC TEMPLATE to control styles
• A bit advanced…more on this later
Back to Output Destinations
• Here is where you choose the output stream(s)
• Popular choices: RTF, HTML, PDF
• You will still get your .lst file (can turn off)
• You can have multiple output destinations for a
single proc call
• Example using both HTML and PDF output (ex3.sas)
• You can even independently control what goes in
each output stream
ex3.sas
options _last_ = anal;
ods html file='ex3.html';
ods pdf file='ex3.pdf';
proc tabulate missing;
class age01 sex01 race duke01 regimp01 bprot01;
table age01 sex01 race duke01 regimp01 all,
bprot01*(n*f=5. pctn<age01 sex01 race duke01 regimp01 all>*f=5.1)
all*(n*f=5. pctn<age01 sex01 race duke01 regimp01 all>*f=5.1)/rts=14;
keylabel all= 'Total' pctn='%';
title 'Patient Characteristics by Parent Protocol';
where lab=1;
run;
ods pdf close;
ods html close;
ex3.lst
Patient Characteristics by Parent Protocol
-------------------------------------------------|
|
Parent Protocol
|
|
|
|-----------------------|
|
|
|
E2284
|
E2288
|
Total
|
|
|-----------+-----------+-----------|
|
| N | % | N | % | N | % |
|------------+-----+-----+-----+-----+-----+-----|
|Age
|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|<= 65
| 129| 61.4| 396| 73.3| 525| 70.0|
|------------+-----+-----+-----+-----+-----+-----|
|> 65
|
81| 38.6| 144| 26.7| 225| 30.0|
|------------+-----+-----+-----+-----+-----+-----|
|Sex
|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|F
|
93| 44.3| 235| 43.5| 328| 43.7|
|------------+-----+-----+-----+-----+-----+-----|
|M
| 117| 55.7| 305| 56.5| 422| 56.3|
|------------+-----+-----+-----+-----+-----+-----|
|Race
|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|.
| 210|100.0|
2| 0.4| 212| 28.3|
|------------+-----+-----+-----+-----+-----+-----|
|White
|
.|
.| 462| 85.6| 462| 61.6|
|------------+-----+-----+-----+-----+-----+-----|
|Black
|
.|
.|
45| 8.3|
45| 6.0|
|------------+-----+-----+-----+-----+-----+-----|
|Other
|
.|
.|
31| 5.7|
31| 4.1|
|------------+-----+-----+-----+-----+-----+-----|
|Dukes Stage |
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|.
|
1| 0.5|
.|
.|
1| 0.1|
|------------+-----+-----+-----+-----+-----+-----|
|B
|
62| 29.5| 113| 20.9| 175| 23.3|
|------------+-----+-----+-----+-----+-----+-----|
|C
| 147| 70.0| 427| 79.1| 574| 76.5|
|------------+-----+-----+-----+-----+-----+-----|
|Reg Implants|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|.
|
1| 0.5|
.|
.|
1| 0.1|
|------------+-----+-----+-----+-----+-----+-----|
|No
| 202| 96.2| 509| 94.3| 711| 94.8|
|------------+-----+-----+-----+-----+-----+-----|
|Yes
|
7| 3.3|
31| 5.7|
38| 5.1|
|------------+-----+-----+-----+-----+-----+-----|
|Total
| 210|100.0| 540|100.0| 750|100.0|
--------------------------------------------------
ex3.html
ex3.pdf
RTF Output for MS Word
To get output into Word, point ODS to the RTF (Rich Text Format) output
destination:
ODS RTF FILE='myFile.rtf';
then open the RTF file in Word. Tabular output will come through as Word
tables, ready for editing and further formatting.
Notes:
By default, SAS puts the titles and footnotes in as headers and footers.
To put them into the body of the document use
ODS RTF FILE='myFile.rtf' BODYTITLE;
ODS will paginate tabular output for a standard 8.5x11 inch page
ODS will wrap tables wider than 8.5 inches
(i.e., it splits columns into two or more tables to conform to page width)
ex3rtf.sas
options _last_ = anal;
/* tagsets.rtf will put true page breaks and “continued” markers */
ods tagsets.rtf file='ex3_tagsets.rtf';
proc tabulate missing;
class age01 sex01 race duke01 regimp01 bprot01;
table age01 sex01 race duke01 regimp01 all,
bprot01*(n*f=5. pctn<age01 sex01 race duke01 regimp01 all>*f=5.1)
all*(n*f=5. pctn<age01 sex01 race duke01 regimp01 all>*f=5.1) / rts=14;
keylabel all= 'Total' pctn='%';
title 'Patient Characteristics by Parent Protocol';
where lab=1;
run;
ods tagsets.rtf close;
ex3_tagsets.rtf
Controlling Output: Advanced
Selecting individual output objects
Example: use ODS with PROC PHREG to save just the
Parameter Estimates table
* Use ODS SELECT output-object; to include output
* Use ODS EXCLUDE output-object; to remove output
* SAS says don’t use both in the same program!
You can limit output to the ODS destination, but keep all the usual
output in the Listing file: (ex4.sas)
ex4.sas
options _last_=anal linesize=100;
ods html file='ex4.html';
/* limit output, but only in HTML file */
ods html select ParameterEstimates;
proc phreg;
model bdfstm*bdfs(0)= age01 sex01 adjuvant duke01 regimp01
obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
title 'DFS: Patient Chars, Stratified';
run;
ods html close;
ex4.lst
DFS: Patient Chars, Stratified
The PHREG Procedure
Model Information
Data Set
USER.ANAL
Dependent Variable
bdfstm
Disease-Free Survival (yr)
Censoring Variable
bdfs
Censoring Value(s)
0
Ties Handling
BRESLOW
Summary of the Number of Event and Censored Values
Percent
Stratum
bprot01
Total
Event
Censored
Censored
1
E2284
201
110
91
45.27
2
E2288
522
208
314
60.15
------------------------------------------------------------------Total
723
318
405
56.02
Convergence Status
Convergence criterion (GCONV=1E-8) satisfied.
Model Fit Statistics
Criterion
-2 LOG L
AIC
SBC
Without
Covariates
3572.913
3572.913
3572.913
With
Covariates
3519.803
3537.803
3571.661
ex4.lst
Testing Global Null Hypothesis: BETA=0
Test
Likelihood Ratio
Score
Wald
Chi-Square
DF
Pr > ChiSq
53.1104
58.9535
56.9963
9
9
9
<.0001
<.0001
<.0001
DFS: Patient Chars, Stratified
The PHREG Procedure
Analysis of Maximum Likelihood Estimates
Variable DF
Parameter Standard
Hazard 95% Hazard Ratio Variable
Estimate
Error Chi-Square Pr > ChiSq Ratio Confidence Limits Label
age01
sex01
adjuvant
duke01
regimp01
obstrc01
diffmod
diffpoor
tum5cm
0.18065
0.37563
-0.22152
0.62128
0.98665
0.21009
-0.05235
0.10048
-0.08005
ex4.html
1
1
1
1
1
1
1
1
1
0.11951
0.11626
0.17279
0.15284
0.20747
0.13121
0.18409
0.21379
0.12170
2.2849
10.4388
1.6436
16.5235
22.6162
2.5639
0.0809
0.2209
0.4327
0.1306
0.0012
0.1998
<.0001
<.0001
0.1093
0.7761
0.6384
0.5107
1.198
1.456
0.801
1.861
2.682
1.234
0.949
1.106
0.923
0.948
1.159
0.571
1.379
1.786
0.954
0.662
0.727
0.727
1.514
1.829
1.124
2.511
4.028
1.596
1.361
1.681
1.172
Age
Sex
Adjuvant Rx
Dukes Stage
Reg Implants
Obstruction
Diff = moderate
Diff = poor
Tumor Size
Controlling Output: Advanced (cont’d)
To get this to work more globally with multiple PROC calls, use
the (PERSIST) option:
ODS SELECT output-object (PERSIST);
ODS HTML FILE='myFile.html';
proc call 1;
proc call 2;
ODS HTML CLOSE;
ODS SELECT ALL;
(ex4long.sas)
Note: You can also suppress the listing (.lst) file with
ODS LISTING CLOSE;
options _last_=anal linesize=100;
ex4long.sas
ods html file='ex4long.html';
ods html select ParameterEstimates (persist); /* limit output only in HTML file */
proc phreg;
model bdfstm*bdfs(0)=
age01 sex01 adjuvant duke01 regimp01 obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
title 'DFS: Patient Chars, Stratified';
run;
proc logistic;
model duke01 =
age01 sex01 adjuvant regimp01 obstrc01 diffmod diffpoor tum5cm / rl;
where lab=1;
title 'LOGISTIC: Patient Chars Predicting Stage';
run;
proc phreg;
model bdfstm*bdfs(0)= age01 / rl;
strata bprot01;
where lab=1;
title 'DFS: Just Age, Stratified';
run;
proc phreg;
model bdfstm*bdfs(0)= sex01 / rl;
strata bprot01;
where lab=1;
title 'DFS: Just Sex, Stratified';
run;
ods html close;
ex4long.html
ex4long.html
ex4long.html
Tracking Output Objects
How do you know what table definition objects are available?
See the SAS documentation or use TRACE!
ODS TRACE ON / LISTING;
proc call(s);
ODS TRACE OFF;
Then view your listing file and look for the "Name:" objects.
(ex5.sas)
Notes:
You can put the trace info in the log file instead by leaving off
/ LISTING
You can select objects by Name, Label or Path with ODS SELECT
Example:
ODS SELECT Phreg.ParameterEstimates
ex5.sas
options _last_=anal linesize=100;
ods trace on / listing;
proc phreg;
model bdfstm*bdfs(0)= age01 sex01 adjuvant duke01
regimp01 obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
title 'DFS: Patient Chars, Stratified';
run;
ods trace off;
ex5.lst
DFS: Patient Chars, Stratified
The PHREG Procedure
Output Added:
------------Name:
ModelInfo
Label:
Model Information
Template:
Stat.Phreg.ModelInfo
Path:
Phreg.ModelInfo
------------Model Information
Data Set
Dependent Variable
Censoring Variable
Censoring Value(s)
Ties Handling
USER.ANAL
bdfstm
bdfs
0
BRESLOW
Disease-Free Survival (yr)
Output Added:
------------Name:
CensoredSummary
Label:
Censored Summary
Template:
Stat.Phreg.CensoredSummary
Path:
Phreg.CensoredSummary
-------------
Summary of the Number of Event and Censored Values
Stratum
bprot01
Total
Event
Censored
Percent
Censored
1
E2284
201
110
91
45.27
2
E2288
522
208
314
60.15
------------------------------------------------------------------Total
723
318
405
56.02
ex5.lst
Output Added:
------------Name:
ConvergenceStatus
Label:
Convergence Status
Template:
Stat.Phreg.ConvergenceStatus
Path:
Phreg.ConvergenceStatus
------------Convergence Status
Convergence criterion (GCONV=1E-8) satisfied.
DFS: Patient Chars, Stratified
The PHREG Procedure
Output Added:
------------Name:
FitStatistics
Label:
Fit Statistics
Template:
Stat.Phreg.FitStatistics
Path:
Phreg.FitStatistics
------------Model Fit Statistics
Criterion
-2 LOG L
AIC
SBC
Without
Covariates
With
Covariates
3572.913
3572.913
3572.913
3519.803
3537.803
3571.661
ex5.lst
Output Added:
------------Name:
GlobalTests
Label:
Global Tests
Template:
Stat.Phreg.GlobalTests
Path:
Phreg.GlobalTests
------------Testing Global Null Hypothesis: BETA=0
Test
Chi-Square
DF
Pr > ChiSq
53.1104
58.9535
56.9963
9
9
9
<.0001
<.0001
<.0001
Likelihood Ratio
Score
Wald
Output Added:
------------Name:
ParameterEstimates
Label:
Parameter Estimates
Template:
Stat.Phreg.ParameterEstimates
Path:
Phreg.ParameterEstimates
-------------
Analysis of Maximum Likelihood Estimates
Variable DF
age01
sex01
adjuvant
duke01
regimp01
obstrc01
1
1
1
1
1
1
Parameter
Estimate
0.18065
0.37563
-0.22152
0.62128
0.98665
0.21009
Standard
Error Chi-Square Pr > ChiSq
0.11951
0.11626
0.17279
0.15284
0.20747
0.13121
2.2849
10.4388
1.6436
16.5235
22.6162
2.5639
0.1306
0.0012
0.1998
<.0001
<.0001
0.1093
Hazard 95% Hazard Ratio
Ratio Confidence Limits Variable Label
1.198
1.456
0.801
1.861
2.682
1.234
0.948
1.159
0.571
1.379
1.786
0.954
1.514
1.829
1.124
2.511
4.028
1.596
Age
Sex
Adjuvant Rx
Dukes Stage
Reg Implants
Obstruction
ODS Selection Debugging
You can use ODS output-destination SHOW; to check the current
status of the ODS selection rules in effect at any time.
Use SHOW and then check the log file (ex6.sas).
Be careful when using multiple SELECT and EXCLUDE statements
with and without output destination qualifiers!
options _last_=anal;
ex6.sas
ods html file='ex6.html';
/* limit output, but only in the HTML file */
ods html select ParameterEstimates;
ods html show;
proc phreg;
model bdfstm*bdfs(0)= age01 sex01 adjuvant duke01
regimp01
obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
title 'DFS: Patient Chars, Stratified';
run;
ods html close;
The SAS System
ex6.log
NOTE: Libref USER was successfully assigned as follows:
Engine:
V8
Physical Name: C:\cygwin\home\pcata\ecog\ods\sasuser
NOTE: Libname LIBRARY refers to the same physical library as USER.
NOTE: Libref LIBRARY was successfully assigned as follows:
Engine:
V8
Physical Name: C:\cygwin\home\pcata\ecog\ods\sasuser
NOTE: AUTOEXEC processing completed.
1
options _last_=anal nodate nonumber linesize=100;
2
3
ods html file='ex4.html';
NOTE: Writing HTML Body file: ex4.html
4
/* limit output, but only in the HTML file */
5
ods html select ParameterEstimates;
6
7
ods html show;
Current HTML select list is:
1. ParameterEstimates
8
9
proc phreg;
10
model bdfstm*bdfs(0)=
11
age01 sex01 adjuvant duke01 regimp01 obstrc01 diffmod diffpoor
tum5cm / rl;
12
strata bprot01;
13
where lab=1;
14
title 'DFS: Patient Chars, Stratified';
15
run;
Getting Results Into Excel
You can use multiple output destinations for Excel: ex4excel.sas
ods html file='ex4.html';
ods tagsets.excelxp body='ex4.xls' style=minimal;
ods select ParameterEstimates;
proc phreg;
model bdfstm*bdfs(0)= age01 sex01 adjuvant duke01 regimp01
obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
title 'DFS: Patient Chars, Stratified';
run;
ods _all_ close;
Using ODS to Create
PowerPoint Slides
Although you can open RTF files in PowerPoint, SAS recommends that you
instead copy and paste tables from Word into PowerPoint after reading RTF
into Word.
SAS 9.4 includes an “ODS POWERPOINT;” statement, but 9.4 is not
officially installed at DFCI yet.
Sending Output Directly to a
Printer or PS file
Use ODS PRINTER PRINTER=printername; to send output
directly to a printer.
Don't forget to use ODS PRINTER CLOSE; at end of PROC calls.
Notes:
* Under Windows, use the windows printer name in quotes, e.g.
PRINTER="pr4"
* Under UNIX, do this:
filename local pipe "lp -d pr4";
ODS PRINTER FILE=local;
To write to a PS file, use ODS PS FILE='filename.ps';
Notes:
* Useful if you want to distill (PDF) the file yourself or if you
want to retain a copy of the file sent to the printer.
* Formatting of the PS file is usually better than the Listing file
(see ex7.sas), so this output might be more generally useful.
* PS files will be in color. Use
ODS PS COLOR=NO FILE='filename.ps';
for black and white.
ex7.sas
proc format;
value dataf 0=‘Long label’ 1=‘Longer label 2='Another long label' 3='Yet another label
4='How about this label?' 5='What about those red sox?';
data work.new;
input x y;
attrib x label='The X variable' format=dataf.;
attrib y label='The Y variable' format=dataf.;
cards;
0 1
0 1
1 1
2 1
3 1
4 1
5 1
2 0
2 1
2 1
2 1
2 2
2 3
2 4
2 5
;
ods ps color=no file='ex7.ps';
proc freq;
tables x*y;
run;
ods ps close;
ex7.lst
The SAS System
The FREQ Procedure
Table of x by y
x(The X variable)
y(The Y variable)
Frequency
Percent
Row Pct Col Pct
|
|
|Long lab|Longer l|Another |Yet anot|How abou|What abo| Total
|el
|abel
|long lab|her labe|t this l|ut those|
|
|
|el
|l
|abel?
|red sox?|
-----------------+--------+--------+--------+--------+--------+--------+
Long label
|
0 |
2 |
0 |
0 |
0 |
0 |
2
|
0.00 | 13.33 |
0.00 |
0.00 |
0.00 |
0.00 | 13.33
|
0.00 | 100.00 |
0.00 |
0.00 |
0.00 |
0.00 |
|
0.00 | 20.00 |
0.00 |
0.00 |
0.00 |
0.00 |
-----------------+--------+--------+--------+--------+--------+--------+
Longer label
|
0 |
1 |
0 |
0 |
0 |
0 |
1
|
0.00 |
6.67 |
0.00 |
0.00 |
0.00 |
0.00 |
6.67
|
0.00 | 100.00 |
0.00 |
0.00 |
0.00 |
0.00 |
|
0.00 | 10.00 |
0.00 |
0.00 |
0.00 |
0.00 |
-----------------+--------+--------+--------+--------+--------+--------+
Another long lab |
1 |
4 |
1 |
1 |
1 |
1 |
9
el
|
6.67 | 26.67 |
6.67 |
6.67 |
6.67 |
6.67 | 60.00
| 11.11 | 44.44 | 11.11 | 11.11 | 11.11 | 11.11 |
| 100.00 | 40.00 | 100.00 | 100.00 | 100.00 | 100.00 |
-----------------+--------+--------+--------+--------+--------+--------+
Yet another labe |
0 |
1 |
0 |
0 |
0 |
0 |
1
l
|
0.00 |
6.67 |
0.00 |
0.00 |
0.00 |
0.00 |
6.67
|
0.00 | 100.00 |
0.00 |
0.00 |
0.00 |
0.00 |
|
0.00 | 10.00 |
0.00 |
0.00 |
0.00 |
0.00 |
-----------------+--------+--------+--------+--------+--------+--------+
How about this l |
0 |
1 |
0 |
0 |
0 |
0 |
1
abel?
|
0.00 |
6.67 |
0.00 |
0.00 |
0.00 |
0.00 |
6.67
|
0.00 | 100.00 |
0.00 |
0.00 |
0.00 |
0.00 |
|
0.00 | 10.00 |
0.00 |
0.00 |
0.00 |
0.00 |
-----------------+--------+--------+--------+--------+--------+--------+
What about those |
0 |
1 |
0 |
0 |
0 |
0 |
1
red sox?
|
0.00 |
6.67 |
0.00 |
0.00 |
0.00 |
0.00 |
6.67
|
0.00 | 100.00 |
0.00 |
0.00 |
0.00 |
0.00 |
|
0.00 | 10.00 |
0.00 |
0.00 |
0.00 |
0.00 |
-----------------+--------+--------+--------+--------+--------+--------+
Total
1
10
1
1
1
1
15
6.67
66.67
6.67
6.67
6.67
6.67
100.00
ex7.ps
Output to PDF
To create PDF files, use
ODS PDF FILE='filename.pdf';
Notes:
* You will automatically get a bookmarked TOC in the PDF file
(ex3.pdf).
* You can control the bookmark labels using
ODS PROCLABEL 'My Procedure Label';
* You can suppress the TOC with NOTOC in the ODS PDF
statement (ex3.sas)
* There is a lot more that we are not covering here…
ex3.pdf
Using ODS to Write to an
Output Data Set
Use the ODS OUTPUT output-object = data-set-name;
statement to create a SAS data set from SAS procedures (ex8.sas)
Note:
You can use KEEP and RENAME in the ODS OUTPUT call to modify the
output data sets.
Ex:
ODS OUTPUT "Parameter Estimates"=Params
(KEEP=Parameter Estimat Probt RENAME=(Probt=Pvalue));
ex8.sas
options _last_=anal;
ods output ParameterEstimates=phregest;
ods listing close;
proc phreg;
model bdfstm*bdfs(0)=
age01 sex01 adjuvant duke01 regimp01 obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
run;
ods output close;
ods listing;
proc contents data=phregest;
run;
ods noptitle;
ods rtf file='ex8.rtf' style=minimal bodytitle;
proc print noobs data=phregest label;
title 'Regression Results';
var Label HazardRatio HRLowerCL HRUpperCL;
label Label="Parameter"
HRLowerCL="95% LCL"
HRUpperCL="95% UCL";
format HazardRatio HRLowerCL HRUpperCL 3.1;
run;
ods rtf close;
ex8.lst
The SAS System
The CONTENTS Procedure
Data Set Name:
Member Type:
Engine:
Created:
Last Modified:
Protection:
Data Set Type:
Label:
USER.PHREGEST
DATA
V8
7:22 Thursday, May 6, 2004
7:22 Thursday, May 6, 2004
Observations:
Variables:
Indexes:
Observation Length:
Deleted Observations:
Compressed:
Sorted:
9
10
0
88
0
NO
NO
Parameter Estimates
-----Engine/Host Dependent Information-----
Data Set Page Size:
Number of Data Set Pages:
First Data Page:
Max Obs per Page:
Obs in First Data Page:
Number of Data Set Repairs:
File Name:
Release Created:
Host Created:
Inode Number:
Access Permission:
Owner Name:
File Size (bytes):
8192
1
1
92
9
0
/homes/pcatae/ods/sasuser/phregest.sas7bdat
8.0202M0
SunOS
8492321
rw-r----pcatae
16384
ex8.lst
-----Alphabetic List of Variables and Attributes----# Variable
Type Len Pos Format
Label
--------------------------------------------------------------------------------5 ChiSq
Num
8 24 10.4
Wald Chi-Square
2 DF
Num
8
0 2.
3 Estimate
Num
8
8 D10.
Parameter Estimate
8 HRLowerCL
Num
8 48 8.3
95% Lower Confidence Limit for Hazard Ratio
9 HRUpperCL
Num
8 56 8.3
95% Upper Confidence Limit for Hazard Ratio
7 HazardRatio Num
8 40 8.3
Hazard Ratio
10 Label
Char 15 72
6 ProbChiSq
Num
8 32 PVALUE6.4 Pr > Chi-Square
4 StdErr
Num
8 16 D10.
Standard Error
1 Variable
Char
8 64
Regression Results
Parameter
Age
Sex
Adjuvant Rx
Dukes Stage
Reg Implants
Obstruction
Diff = moderate
Diff = poor
Tumor Size
Hazard
Ratio
1.2
1.5
0.8
1.9
2.7
1.2
0.9
1.1
0.9
95%
LCL
95%
UCL
0.9
1.2
0.6
1.4
1.8
1.0
0.7
0.7
0.7
1.5
1.8
1.1
2.5
4.0
1.6
1.4
1.7
1.2
ex8.rtf
Working with Styles
* Styles control the look and layout of the ODS output
* Default styles depend upon the output destination
PROC TEMPLATE
is used to create output styles
* To see the system’s built in styles run stylelist.sas:
PROC TEMPLATE;
LIST STYLES;
RUN;
Here are some styles:
Obs Path
Type
-------------------------------------------1
Styles
Dir
2
Styles.BarrettsBlue
Style
3
Styles.Beige
Style
4
Styles.Brick
Style
5
Styles.Brown
Style
6
Styles.D3d
Style
7
Styles.Default
Style
8
Styles.Minimal
Style
9
Styles.NoFontDefault Style
10 Styles.Printer
Style
11
Styles.Rtf
Style
12 Styles.Sasweb
Style
13 Styles.Statdoc
Style
14 Styles.Theme
Style
15 Styles.fancyPrinter
Style
16 Styles.sansPrinter
Style
Specifying Styles
Use the STYLE= option to change styles
To see the styles in action, look at showstylesrtf.sas
(code from ODS: The Basics, p. 271)
Some useful, basic styles are Analysis, Journal, Minimal
(ex8.sas)
To see the source code for one or more style definitions use
PROC TEMPLATE;
SOURCE Styles.Default;
RUN;
(defaultsource.sas, defaultsource.log)
defaultsource.log
define style Styles.Default;
class fonts
"Fonts used in the default style" /
'TitleFont2' = ("<sans-serif>, Helvetica, sans-serif",4,bold italic)
'TitleFont' = ("<sans-serif>, Helvetica, sans-serif",5,bold italic)
'StrongFont' = ("<sans-serif>, Helvetica, sans-serif",4,bold)
'EmphasisFont' = ("<sans-serif>, Helvetica, sans-serif",3,italic)
'FixedEmphasisFont' = ("<monospace>, Courier, monospace",2,italic)
'FixedStrongFont' = ("<monospace>, Courier, monospace",2,bold)
'FixedHeadingFont' = ("<monospace>, Courier, monospace",2)
'BatchFixedFont' = ("SAS Monospace, <monospace>, Courier, monospace",2)
'FixedFont' = ("<monospace>, Courier",2)
'headingEmphasisFont' = ("<sans-serif>, Helvetica, sans-serif",4,bold
italic)
'headingFont' = ("<sans-serif>, Helvetica, sans-serif",4,bold)
'docFont' = ("<sans-serif>, Helvetica, sans-serif",3);
class color_list
"Colors used in the default style" /
'fgB2' = cx0066AA
'fgB1' = cx004488
'fgA4' = cxAAFFAA
showstylertf.sas
ods output Stats(match_all=mvar)=Temp1;
proc template;
list;
run;
ods output close;
data TemplateListing;
length type $12 path $255;
set &mvar;
if type="Style";
run;
data _null_;
set TemplateListing end=eof;
retain Counter 1;
if eof then call symput('NumStyles', Counter);
StyleName=Path;
StyleNum=trim(left(compress("Style"||Counter)));
call symput(StyleNum,StyleName);
Counter+1;
run;
Data Test;
input A B C;
cards;
1 2 3
4 5 6
7 8 9
;
run;
%Macro DisplayStyles;
ods listing close;
%Do C=1 %to &NumStyles;
ods rtf file="styletest&C..rtf" style=&&Style&C;
title 'Available Styles';
title2 "This Style is &&Style&C";
ods proclabel "This Style is &&Style&C";
proc print data=Test;
run;
%End;
ods rtf close;
%Mend DisplayStyles;
%DisplayStyles;
styletest1.rtf
Modifying Styles
This can be a bit tricky and detailed.
Use PROC TEMPLATE with the DEFINE statement. Let's modify the minimal
style to remove the frame and cell borders and instead use rules to separate the
header from the rest of the table (mystyle.sas):
proc template;
delete pjcstyle;
run;
proc template;
define style pjcstyle;
parent=styles.minimal;
replace output /
rules = groups <-- betw head, body, foot; changed from all (every line)
frame = hsides <-- horiz sides only; changed from box (both horiz & vert)
cellpadding = 7
cellspacing = 1
borderwidth = 3;
replace systemtitle from titlesandfooters /
font_face=arial
font_style=italic;
end;
run;
Previous style with full frame and cell borders
Now use the new style via the STYLE= option in the ODS RTF statement (ex9.sas).
ods output ParameterEstimates=phregest;
ods listing close;
proc phreg;
model bdfstm*bdfs(0)=
age01 sex01 adjuvant duke01 regimp01 obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
run;
ods output close;
ods listing;
proc contents data=phregest;
run;
ods noptitle;
ods rtf file='ex9.rtf' style=pjcstyle bodytitle;
proc print noobs data=phregest label;
title 'Regression Results';
var Label HazardRatio HRLowerCL HRUpperCL;
label Label="Parameter"
HRLowerCL="95% LCL"
HRUpperCL="95% UCL";
format HazardRatio HRLowerCL HRUpperCL 3.1;
run;
ods rtf close;
ex9.rtf
Notes:
* Custom styles are stored in SASUSER.TEMPLAT
* System styles are stored in SASHELP.TMPLMST
* ODS uses this
ODS PATH SASUSER.TEMPLAT(UPDATE)
SASHELP.TMPLMST(READ);
to find system and custom styles when SAS runs.
* See ODS: The Basics, page 146 for more on this.
Putting It All Together
Let’s review ex9.sas one more time.
In this code we:
* Choose to output just the PHREG parameter estimates to a
separate SAS data set
* Turn off the listing file during the regression run
* Open RTF output to accept the results, specifying
* No procedure titles (NOPTITLE)
* A custom-built style, with new table borders and header font
* Formatted RTF output using PROC PRINT variable labels and
output formats.
The above gives us customized output ready for a final report.
ex9.sas
options _last_=anal;
ods output ParameterEstimates=phregest;
ods listing close;
proc phreg;
model bdfstm*bdfs(0)=
age01 sex01 adjuvant duke01 regimp01 obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
run;
ods output close;
ods listing;
proc contents data=phregest;
run;
ods noptitle;
ods rtf file='ex9.rtf' style=pjcstyle bodytitle;
proc print noobs data=phregest label;
title 'Regression Results';
var Label HazardRatio HRLowerCL HRUpperCL;
label Label="Parameter"
HRLowerCL="95% LCL"
HRUpperCL="95% UCL";
format HazardRatio HRLowerCL HRUpperCL 3.1;
run;
ods rtf close;
An Easier Way to Use Styles
PROC REPORT, TABULATE
and PRINT support changing styles on the
fly within the procedure code.
Let’s revisit the last example to see how this works.
Old code that called my own style (ex9.sas):
ods rtf file='ex9.rtf' style=pjcstyle bodytitle;
proc print noobs data=phregest label;
title 'Regression Results';
var Label HazardRatio HRLowerCL HRUpperCL;
label Label="Parameter
HRLowerCL="95% LCL
HRUpperCL="95% UCL";
format HazardRatio HRLowerCL HRUpperCL 3.1;
run;
ods rtf close;
But we can also change the style right inside PROC PRINT (ex10.sas)
ods rtf file='ex10.rtf' style=pjcstyle bodytitle;
proc print noobs data=phregest label
style(Header)=[font_face='Arial']
style(Data)=[font_face='Arial'];
title 'Regression Results';
var Label HazardRatio HRLowerCL HRUpperCL;
label Label="Parameter"
HRLowerCL="95% LCL"
HRUpperCL="95% UCL";
format HazardRatio HRLowerCL HRUpperCL 3.1;
run;
ods rtf close;
ex10.sas
ods output ParameterEstimates=phregest;
ods listing close;
proc phreg;
model bdfstm*bdfs(0)=
age01 sex01 adjuvant duke01 regimp01 obstrc01 diffmod diffpoor tum5cm / rl;
strata bprot01;
where lab=1;
run;
ods output close;
ods listing;
proc contents data=phregest;
run;
ods noptitle;
ods rtf file='ex10.rtf' style=pjcstyle bodytitle;
proc print noobs data=phregest label
style(Header)=[font_face='Arial']
style(Data)=[font_face='Arial'];
title 'Regression Results';
var Label HazardRatio HRLowerCL HRUpperCL;
label Label="Parameter
HRLowerCL="95% LCL
HRUpperCL="95% UCL";
format HazardRatio HRLowerCL HRUpperCL 3.1;
run;
ods rtf close;
ex10.rtf
Another modification:
We can make most of the style changes inside PROC PRINT:
ods rtf file='ex10.rtf' style=minimal bodytitle;
proc print noobs data=phregest label
style=[rules=groups frame=hsides]
style(Header)=[font_face='Arial']
style(Data)=[font_face='Arial'];
title 'Regression Results';
var Label HazardRatio HRLowerCL HRUpperCL;
label Label="Parameter
HRLowerCL="95% LCL
HRUpperCL="95% UCL";
format HazardRatio HRLowerCL HRUpperCL 3.1;
run;
ods rtf close;
But this method won’t change the font for the title statements.
A Little About Graphics
You can easily embed graphics in RTF files (ex11.sas)
options _last_=anal;
/* embeds K-M plot directly in RTF file */
/* also produces SurvivalPlot.png in cwd */
ods tagsets.rtf file='ex11.rtf';
ods graphics on;
proc lifetest notable;
time bdfstm*bdfs(0);
survival plots=(survival);
strata bprot01;
where lab=1;
title 'DFS by Protocol';
run;
ods graphics off;
ods tagsets.rtf close;
References
Output Delivery System: The Basics and Beyond
by Haworth, Zender, and Burlew (SAS Press)
Output Delivery System: The Basics
by Lauren E. Haworth (SAS Books by Users Press)
The Complete Guide to the SAS Output Delivery System, Version 8
SAS User's Guide No. 57241
Quick Results with the Output Delivery System
By Sunil K. Gupta (SAS Books by Users Press, No. 58458)
Source of example files and this talk: ~pcatae/ods
Further Explorations
Other things that we have not had time to cover:
* Appending to existing output destination files
- See appendhtml.sas, appendhtml.lst and append.html
- See also Complete Guide, page 100
- Does not work with RTF
* Traffic Lighting: Conditionally writing formats based on data
values
- For example, highlight all values of X in red when X is
greater than some value Y
- See ODS: The Basics, page 218
* More on customizing procedure results with styles
- For example, changing PROC UNIVARIATE to show only mean,
median and range, all with only 2 decimal places.
- See Complete Guide, page 16
* Using sophisticated selection lists with multiple procedure steps
- For example, getting just the Fit Statistics from 20 calls to
PROC REG and GLM
- See Complete Guide, page 86
* Using ODS in the DATA Step
- See Basics and Beyond, Ch 9; Complete Guide, page 105
• Using ODS with CSV and LaTeX destinations
- See ODS MARKUP.
appendhtml.sas
options _last_ = anal;
filename myreport 'append.html';
ods html file=myreport (no_bottom_matter);
proc tabulate missing;
class age01 sex01 race duke01 regimp01 bprot01;
table age01 sex01 race duke01 regimp01 all,
bprot01*(n*f=5. pctn<age01 sex01 race duke01 regimp01 all>*f=5.1)
all*(n*f=5. pctn<age01 sex01 race duke01 regimp01 all>*f=5.1)/rts=14;
keylabel all= 'Total' pctn='%';
title 'Patient Characteristics by Parent Protocol';
where lab=1;
run;
ods html close;
proc freq;
tables sex01;
run;
filename myreport 'append.html' mod;
ods html file=myreport (no_top_matter);
proc freq;
tables sex01*race;
run;
ods html close;
appendhtml.lst
Patient Characteristics by Parent Protocol
-------------------------------------------------|
|
Parent Protocol
|
|
|
|-----------------------|
|
|
|
E2284
|
E2288
|
Total
|
|
|-----------+-----------+-----------|
|
| N | % | N | % | N | % |
|------------+-----+-----+-----+-----+-----+-----|
|Age
|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|<= 65
| 129| 61.4| 396| 73.3| 525| 70.0|
|------------+-----+-----+-----+-----+-----+-----|
|> 65
|
81| 38.6| 144| 26.7| 225| 30.0|
|------------+-----+-----+-----+-----+-----+-----|
|Sex
|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|F
|
93| 44.3| 235| 43.5| 328| 43.7|
|------------+-----+-----+-----+-----+-----+-----|
|M
| 117| 55.7| 305| 56.5| 422| 56.3|
|------------+-----+-----+-----+-----+-----+-----|
|Race
|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|.
| 210|100.0|
2| 0.4| 212| 28.3|
|------------+-----+-----+-----+-----+-----+-----|
|White
|
.|
.| 462| 85.6| 462| 61.6|
|------------+-----+-----+-----+-----+-----+-----|
|Black
|
.|
.|
45| 8.3|
45| 6.0|
|------------+-----+-----+-----+-----+-----+-----|
|Other
|
.|
.|
31| 5.7|
31| 4.1|
|------------+-----+-----+-----+-----+-----+-----|
|Dukes Stage |
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|.
|
1| 0.5|
.|
.|
1| 0.1|
|------------+-----+-----+-----+-----+-----+-----|
|B
|
62| 29.5| 113| 20.9| 175| 23.3|
|------------+-----+-----+-----+-----+-----+-----|
|C
| 147| 70.0| 427| 79.1| 574| 76.5|
|------------+-----+-----+-----+-----+-----+-----|
|Reg Implants|
|
|
|
|
|
|
|------------|
|
|
|
|
|
|
|.
|
1| 0.5|
.|
.|
1| 0.1|
|------------+-----+-----+-----+-----+-----+-----|
|No
| 202| 96.2| 509| 94.3| 711| 94.8|
|------------+-----+-----+-----+-----+-----+-----|
|Yes
|
7| 3.3|
31| 5.7|
38| 5.1|
|------------+-----+-----+-----+-----+-----+-----|
|Total
| 210|100.0| 540|100.0| 750|100.0|
--------------------------------------------------
appendhtml.lst
Patient Characteristics by Parent Protocol
The FREQ Procedure
Sex
Cumulative
Cumulative
sex01
Frequency
Percent
Frequency
Percent
---------------------------------------------------------F
1802
45.22
1802
45.22
M
2183
54.78
3985
100.00
Patient Characteristics by Parent Protocol
The FREQ Procedure
Table of sex01 by RACE
sex01(Sex)
RACE(Race)
Frequency|
Percent |
Row Pct |
Col Pct |White
|Black
|Other
| Total
---------+--------+--------+--------+
F
|
1350 |
174 |
78 |
1602
| 38.12 |
4.91 |
2.20 | 45.24
| 84.27 | 10.86 |
4.87 |
| 44.61 | 50.88 | 45.09 |
---------+--------+--------+--------+
M
|
1676 |
168 |
95 |
1939
| 47.33 |
4.74 |
2.68 | 54.76
| 86.44 |
8.66 |
4.90 |
| 55.39 | 49.12 | 54.91 |
---------+--------+--------+--------+
Total
3026
342
173
3541
85.46
9.66
4.89
100.00
Frequency Missing = 444
append.html
append.html
© Copyright 2026 Paperzz