The SAS Output Delivery System and reporting techniques

How to write ods latex template

Accepted Solution Solved
Reply
Contributor
Posts: 24
Accepted Solution

How to write ods latex template

Based on this document:

 

https://support.sas.com/resources/papers/proceedings14/2033-2014.pdf

 

I created the attached result and using the attached code,

figure.png

but I want to produce my own template that creates output as this (tables with multi-rows and partial grids):

figure.png

 

Does anyone know how to achieve this? Or a good source to learn writing the language used in ods template. Much thanks! 

Attachment
Attachment

Accepted Solutions
Solution
‎06-20-2018 08:12 PM
SAS Super FREQ
Posts: 9,426

Re: How to write ods latex template

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:

for_latex.png

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;

 

 

 

View solution in original post


All Replies
Super User
Posts: 23,992

Re: How to write ods latex template

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.

http://www2.sas.com/proceedings/forum2008/173-2008.pdf

Solution
‎06-20-2018 08:12 PM
SAS Super FREQ
Posts: 9,426

Re: How to write ods latex template

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:

for_latex.png

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;

 

 

 

SAS Super FREQ
Posts: 9,426

Re: How to write ods latex template

Posted in reply to Cynthia_sas

...And, with a slightly different structure to the input data, you can get the break in the line above the 2 groups:

diff_latex.png

 

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;
Contributor
Posts: 24

Re: How to write ods latex template

Posted in reply to Cynthia_sas

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!

Super User
Posts: 23,992

Re: How to write ods latex template

SAS Super FREQ
Posts: 9,426

Re: How to write ods latex template

Hi, How odd...somehow, it looks like you might have used the wrong data with one of my programs. Each program was designed to work with the data structure that I used. Did you run my code unchanged using the data intended for each program?

cynthia
Contributor
Posts: 24

Re: How to write ods latex template

Posted in reply to Cynthia_sas
Yes, I runned it with everything unchanged. Note that I am using SAS on WRDS
Super User
Posts: 23,992

Re: How to write ods latex template

Post the log. 

Contributor
Posts: 24

Re: How to write ods latex template

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
SAS Super FREQ
Posts: 9,426

Re: How to write ods latex template

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

Contributor
Posts: 24

Re: How to write ods latex template

Posted in reply to Cynthia_sas
That works perfectly! Thank you!
Contributor
Posts: 24

Re: How to write ods latex template

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. 

Super User
Posts: 23,992

Re: How to write ods latex template


@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. 

Contributor
Posts: 24

Re: How to write ods latex template

Thank you for the information on the website! I will see if I can find anything useful on this site
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 14 replies
  • 718 views
  • 2 likes
  • 3 in conversation