- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Based on this document:
https://support.sas.com/resources/papers/proceedings14/2033-2014.pdf
I created the attached result and using the attached code,
but I want to produce my own template that creates output as this (tables with multi-rows and partial grids):
Does anyone know how to achieve this? Or a good source to learn writing the language used in ods template. Much thanks!
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, @Reeza for the shout out on the paper. I actually mocked up some fake (summarized) data for this question and came up with this using PROC REPORT and ODS RTF:
I put ODS LATEX statements in the code too, but I don't have an application to render the LaTeX files (and I don't do command lines any more).
Anyway, I agree -- writing a template for a table like this seems unnecessary to me when PROC REPORT can do the heavy lifting.
Cynthia
Here's all the code, fake data and all:
data forlatex;
length Grp $5 Type $6 Cat $4;
infile datalines dlm=' ';
input Type $ Cat $ value Grp $;
datalines;
Market Low -32.83 EWAVG
Market 2 -3.36 EWAVG
Market 3 12.48 EWAVG
Market 4 31.22 EWAVG
Market High 97.89 EWAVG
Micro Low -34.76 EWAVG
Micro 2 -3.60 EWAVG
Micro 3 12.36 EWAVG
Micro 4 31.29 EWAVG
Micro High 104.34 EWAVG
Small Low -29.12 EWAVG
Small 2 -3.22 EWAVG
Small 3 12.56 EWAVG
Small 4 31.31 EWAVG
Small High 91.90 EWAVG
Big Low -25.21 EWAVG
Big 2 -2.90 EWAVG
Big 3 12.60 EWAVG
Big 4 30.93 EWAVG
Big High 80.46 EWAVG
Market Low 15.56 XSTD
Market 2 4.82 XSTD
Market 3 4.51 XSTD
Market 4 6.81 XSTD
Market High 61.57 XSTD
Micro Low 16.00 XSTD
Micro 2 4.81 XSTD
Micro 3 4.49 XSTD
Micro 4 6.81 XSTD
Micro High 65.95 XSTD
Small Low 13.49 XSTD
Small 2 4.84 XSTD
Small 3 4.52 XSTD
Small 4 6.83 XSTD
Small High 53.43 XSTD
Big Low 11.15 XSTD
Big 2 4.77 XSTD
Big 3 4.50 XSTD
Big 4 6.74 XSTD
Big High 41.73 XSTD
;
run;
proc format ;
value $grpfmt 'EWAVG'='Average of Annual ^{newline 1}EW Average Values^{newline 1} All Stocks'
'XSTD' = 'Average of Annual Cross-^{newline 1}Section Standard Deviations^{newline 1} All Stocks';
run;
ods escapechar='^';
ods rtf file='c:\temp\try_report.rtf' style=journal;
ods latex path='c:\temp' file='try_report.tex' style=journal;
Title 'Show in RTF and LaTeX';
proc report data=forlatex;
column Type Grp,Cat,value;
define Type / group order=data ' ';
define Grp / across order=data ' ' f=$grpfmt.;
define Cat / across order=data ' '
style(header)={bordertopcolor=black bordertopstyle=solid bordertopwidth=2px};
define value / analysis ' ';
compute before / style={just=l fontweight=bold};
line 'Sorting on Momentum, ^{style[fontstyle=italic]Mom}';
endcomp;
run;;
ods latex close;
ods rtf close;
title;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Are you looking for a formatted report or do you really need latex?
SAS will output nice clean tables to PDF directly with less work than the ODS template.
Page 9 here illustrates an example of clinical reports.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, @Reeza for the shout out on the paper. I actually mocked up some fake (summarized) data for this question and came up with this using PROC REPORT and ODS RTF:
I put ODS LATEX statements in the code too, but I don't have an application to render the LaTeX files (and I don't do command lines any more).
Anyway, I agree -- writing a template for a table like this seems unnecessary to me when PROC REPORT can do the heavy lifting.
Cynthia
Here's all the code, fake data and all:
data forlatex;
length Grp $5 Type $6 Cat $4;
infile datalines dlm=' ';
input Type $ Cat $ value Grp $;
datalines;
Market Low -32.83 EWAVG
Market 2 -3.36 EWAVG
Market 3 12.48 EWAVG
Market 4 31.22 EWAVG
Market High 97.89 EWAVG
Micro Low -34.76 EWAVG
Micro 2 -3.60 EWAVG
Micro 3 12.36 EWAVG
Micro 4 31.29 EWAVG
Micro High 104.34 EWAVG
Small Low -29.12 EWAVG
Small 2 -3.22 EWAVG
Small 3 12.56 EWAVG
Small 4 31.31 EWAVG
Small High 91.90 EWAVG
Big Low -25.21 EWAVG
Big 2 -2.90 EWAVG
Big 3 12.60 EWAVG
Big 4 30.93 EWAVG
Big High 80.46 EWAVG
Market Low 15.56 XSTD
Market 2 4.82 XSTD
Market 3 4.51 XSTD
Market 4 6.81 XSTD
Market High 61.57 XSTD
Micro Low 16.00 XSTD
Micro 2 4.81 XSTD
Micro 3 4.49 XSTD
Micro 4 6.81 XSTD
Micro High 65.95 XSTD
Small Low 13.49 XSTD
Small 2 4.84 XSTD
Small 3 4.52 XSTD
Small 4 6.83 XSTD
Small High 53.43 XSTD
Big Low 11.15 XSTD
Big 2 4.77 XSTD
Big 3 4.50 XSTD
Big 4 6.74 XSTD
Big High 41.73 XSTD
;
run;
proc format ;
value $grpfmt 'EWAVG'='Average of Annual ^{newline 1}EW Average Values^{newline 1} All Stocks'
'XSTD' = 'Average of Annual Cross-^{newline 1}Section Standard Deviations^{newline 1} All Stocks';
run;
ods escapechar='^';
ods rtf file='c:\temp\try_report.rtf' style=journal;
ods latex path='c:\temp' file='try_report.tex' style=journal;
Title 'Show in RTF and LaTeX';
proc report data=forlatex;
column Type Grp,Cat,value;
define Type / group order=data ' ';
define Grp / across order=data ' ' f=$grpfmt.;
define Cat / across order=data ' '
style(header)={bordertopcolor=black bordertopstyle=solid bordertopwidth=2px};
define value / analysis ' ';
compute before / style={just=l fontweight=bold};
line 'Sorting on Momentum, ^{style[fontstyle=italic]Mom}';
endcomp;
run;;
ods latex close;
ods rtf close;
title;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
...And, with a slightly different structure to the input data, you can get the break in the line above the 2 groups:
It just depends on which form of data there is.
Cynthia
Here's the alternate data and program:
data fakedata;
length Type $6 Cat $4;
infile datalines dlm=' ';
input Type $ Cat $ EWVAL XSVAL ;
datalines;
Market Low -32.83 15.56
Market 2 -3.36 4.82
Market 3 12.48 4.51
Market 4 31.22 6.81
Market High 97.89 61.57
Micro Low -34.76 16
Micro 2 -3.6 4.81
Micro 3 12.36 4.49
Micro 4 31.29 6.81
Micro High 104.34 65.95
Small Low -29.12 13.49
Small 2 -3.22 4.84
Small 3 12.56 4.52
Small 4 31.31 6.83
Small High 91.9 53.43
Big Low -25.21 11.15
Big 2 -2.9 4.77
Big 3 12.6 4.5
Big 4 30.93 6.74
Big High 80.46 41.73
;
run;
ods rtf file='c:\temp\diff_data.rtf' style=journal;
ods latex path='c:\temp' file='diff_data.tex' style=journal;
Title 'Show in RTF and LaTeX';
proc report data=fakedata;
column Type ('Average of Annual ^{newline 1}EW Average Values^{newline 1} All Stocks' Cat,EWVAL) blank
('Average of Annual Cross-^{newline 1}Section Standard Deviations^{newline 1} All Stocks' Cat,XSVAL);
define Type / group order=data ' ';
define Cat / across order=data ' '
style(header)={bordertopcolor=black bordertopstyle=solid bordertopwidth=2px};
define ewval / analysis ' ';
define blank / computed ' '
style(header)={bordertopcolor=white bordertopstyle=none bordertopwidth=0px};
define xsval / analysis ' ';
compute blank;
blank = ' ';
endcomp;
compute before / style={just=l fontweight=bold};
line 'Sorting on Momentum, ^{style[fontstyle=italic]Mom}';
endcomp;
run;;
ods latex close;
ods rtf close;
title;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi Cynthia,
Thank your very much for the detailed solution using Proc Report. This is indeed is a great alternative to directly producing latex tables. Though the .tex produced in this process does not give nice results, the rtf version of the table looks great! But the second version has the table structure but there's no entries on data.
Could you point me to guide that breaks down components in the proc report command? I can't really understand the how the code works exactly now.
Thank you very much!
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
PROC REPORT documentation
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
cynthia
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Post the log.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
here's the log
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK; SYMBOLGEN: Macro variable _SASWSTEMP_ resolves to /home/columbia/zz71/.sasstudio/.images/9097d6ba-62ba-4ce8-9a3a-bfd78 519bad7 SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing. SYMBOLGEN: Macro variable GRAPHINIT resolves to GOPTIONS RESET=ALL GSFNAME=_GSFNAME; NOTE: ODS statements in the SAS Studio environment may disable some output features. 73 74 options validvarname=V7 symbolgen mprint mlogicnest spool details; 75 libname mast '/wrdslin/nyse/sasdata/taqs'; NOTE: Libref MAST was successfully assigned as follows: Engine: V9 Physical Name: /wrdslin/nyse/sasdata/taqs 76 libname zz02 '/scratch/columbia/zz89'; NOTE: Libref ZZ02 was successfully assigned as follows: Engine: V9 Physical Name: /scratch/columbia/zz89 77 libname zz '/home/columbia/zz71/zz'; NOTE: Libref ZZ was successfully assigned as follows: Engine: V9 Physical Name: /home/columbia/zz71/zz 78 79 data fakedata; 80 length Type $6 Cat $4; 81 infile datalines dlm=' '; 82 input Type $ Cat $ EWVAL XSVAL ; 83 datalines; NOTE: Invalid data for EWVAL in line 86 1-19. NOTE: Invalid data for XSVAL in line 87 1-19. RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+---- 87 CHAR Market.4.31.22.6.81 ZONE 467667030332330323322222222222222222222222222222222222222222222222222 NUMR D12B5494931E2296E8100000000000000000000000000000000000000000000000000 70 NOTE: Invalid data errors for file CARDS occurred outside the printed range. NOTE: Increase available buffer lines with the INFILE n= option. Type=Market Cat=Mark EWVAL=. XSVAL=. _ERROR_=1 _N_=1 NOTE: Invalid data for EWVAL in line 90 1-17. NOTE: Invalid data for XSVAL in line 91 1-18. 91 CHAR Micro.3.12.36.4.49 ZONE 466760303323303233222222222222222222222222222222222222222222222222222 NUMR D932F93912E3694E49000000000000000000000000000000000000000000000000000 70 NOTE: Invalid data errors for file CARDS occurred outside the printed range. NOTE: Increase available buffer lines with the INFILE n= option. Type=Market Cat=Micr EWVAL=. XSVAL=. _ERROR_=1 _N_=2 NOTE: Invalid data for EWVAL in line 94 1-22. NOTE: Invalid data for XSVAL in line 95 1-18. 95 CHAR Small.2.-3.22.4.84 ZONE 566660302323303233222222222222222222222222222222222222222222222222222 NUMR 3D1CC929D3E2294E84000000000000000000000000000000000000000000000000000 70 NOTE: Invalid data errors for file CARDS occurred outside the printed range. NOTE: Increase available buffer lines with the INFILE n= option. Type=Micro Cat=Micr EWVAL=. XSVAL=. _ERROR_=1 _N_=3 NOTE: Invalid data for EWVAL in line 98 1-21. NOTE: Invalid data for XSVAL in line 99 1-20. 99 CHAR Big.Low.-25.21.11.15 ZONE 466046702332330332332222222222222222222222222222222222222222222222222 NUMR 2979CF79D25E21911E150000000000000000000000000000000000000000000000000 70 NOTE: Invalid data errors for file CARDS occurred outside the printed range. NOTE: Increase available buffer lines with the INFILE n= option. Type=Small Cat=Smal EWVAL=. XSVAL=. _ERROR_=1 _N_=4 NOTE: Invalid data for EWVAL in line 102 1-16. NOTE: Invalid data for XSVAL in line 103 1-20. 103 CHAR Big.High.80.46.41.73 ZONE 466046660332330332332222222222222222222222222222222222222222222222222 NUMR 29798978980E46941E730000000000000000000000000000000000000000000000000 70 NOTE: Invalid data errors for file CARDS occurred outside the printed range. NOTE: Increase available buffer lines with the INFILE n= option. Type=Big2 Cat=Big EWVAL=. XSVAL=. _ERROR_=1 _N_=5 NOTE: SAS went to a new line when INPUT statement reached past the end of a line. NOTE: The data set WORK.FAKEDATA has 5 observations and 4 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.00 seconds 104 ; 105 run; 106 107 108 ods rtf file='/scratch/columbia/zz89/diff_data.rtf' style=journal; NOTE: Writing RTF Body file: /scratch/columbia/zz89/diff_data.rtf 109 ods latex path='/scratch/columbia/zz89' file='diff_data.tex' 109 ! style=journal; NOTE: Writing LATEX Body file: diff_data.tex 110 Title 'Show in RTF and LaTeX'; 111 proc report data=fakedata; 112 column Type ('Average of Annual ^{newline 1}EW Average 112 ! Values^{newline 1} All Stocks' Cat,EWVAL) blank 113 ('Average of Annual Cross-^{newline 1}Section Standard 113 ! Deviations^{newline 1} All Stocks' Cat,XSVAL); 114 define Type / group order=data ' '; 115 define Cat / across order=data ' ' 116 style(header)={bordertopcolor=black bordertopstyle=solid 116 ! bordertopwidth=2px}; 117 define ewval / analysis ' '; 118 define blank / computed ' ' 119 style(header)={bordertopcolor=white bordertopstyle=none 119 ! bordertopwidth=0px}; 120 define xsval / analysis ' '; 121 compute blank; 122 blank = ' '; 123 endcomp; 124 compute before / style={just=l fontweight=bold}; 125 line 'Sorting on Momentum, ^{style[fontstyle=italic]Mom}'; 126 endcomp; 127 run; 127 ! ; NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column). 1:10 NOTE: There were 5 observations read from the data set WORK.FAKEDATA. NOTE: PROCEDURE REPORT used (Total process time): real time 0.11 seconds cpu time 0.04 seconds 128 ods latex close; 129 ods rtf close; 130 title; 131 132 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK; SYMBOLGEN: Macro variable GRAPHTERM resolves to GOPTIONS NOACCESSIBLE; 145
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi:
It looks like the DATA step program to make the fake data never worked right. Here's a comma-separated version of the fake data file for the second example:
data fakedata;
length Type $6 Cat $4;
infile datalines dlm=',' dsd;
input Type $ Cat $ EWVAL XSVAL ;
datalines;
Market,Low,-32.83,15.56
Market,2,-3.36,4.82
Market,3,12.48,4.51
Market,4,31.22,6.81
Market,High,97.89,61.57
Micro,Low,-34.76,16
Micro,2,-3.6, 4.81
Micro,3,12.36,4.49
Micro,4,31.29,6.81
Micro,High,104.34,65.95
Small,Low,-29.12,13.49
Small,2,-3.22,4.84
Small,3,12.56,4.52
Small,4,31.31,6.83
Small,High,91.9, 53.43
Big,Low,-25.21,11.15
Big,2,-2.9,4.77
Big,3,12.6,4.5
Big,4,30.93,6.74
Big,High,80.46,41.73
;
run;
The rest of the program is the same.
Cynthia
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi Reeza,
Thank you for your response.
I do need article-ready tables from SAS and since the result will include a large number of tables, it is much easier to do this by some script/template.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
@Sasadomo wrote:
Hi Reeza,
Thank you for your response.
I do need article-ready tables from SAS and since the result will include a large number of tables, it is much easier to do this by some script/template.
Agreed, but latex is possible but not worth the effort would be my suggestion.
ODS PDF and PROC REPORT is enough. If these are clinical reports search lexjansen.com for lots of example code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content