Changing third level nodes in proc report using proc documents - sas

I am trying to make a customize labels in proc report using proc documents. Basically i want the table to have just one level of headers
I move the proc report table out under the Dir and then relabel the table. But even after that, the TOC still have a subnode.
Here is my MWE
/*proc greplay nofs igout=work.gseg; */
/* delete _all_; */
/*run; */
/*quit; */
ods listing close;
ods pdf file="before.pdf" contents=yes ;
ods document name=test(write);
title1 'Using Proc REPORT';
title2 'Simple Report';
* Simple report;
proc report data=test nofs;
columns name sex age;
define name / display;
define sex / display;
define age / display;
run;
ods document close;
ods pdf close;
proc document name=test;
list / levels=all details; run;
/*-- Move output from under folders --*/
move \Report#1\Report#1\Report#1 to ^;run;
/*-- Verify document leaf nodes moved out from under the folders --*/
list / levels=all details; run;
setlabel \Work.test\Report#2 "Custom Heading"; run;
/*-- Delete folders --*/
delete \Report#1/* , \Report#2 */; run;
/*-- Verify folders were deleted --*/
list / levels=all details; run;
/*-- Close Listing Destination --*/
ods listing close;
/*-- Replay output (Print and GPlot to PDF) --*/
ods pdf file="after.pdf" contents=yes ;
replay;
run;
ods pdf close;
quit;

Your proc document looks fine for me. The point is you need to move all higher level objects to first level.
But you will still get the Table * marks in your TOC introduced by proc report.
To remove those marks, first add option contents="" in your proc report, which removes the higher level TOC contents. This is necessary no matter what types of ods destination you want, either rtf or pdf.
proc report data=test nofs contents="";
columns name sex age;
define name / display;
define sex / display;
define age / display;
break before name / contents="" page;
run;
Then you need pdftoc=1 for your ods pdf statement, which limits your TOC to first level.
proc document name=test;
ods pdf file="after.pdf" pdftoc=1 contents=on;
replay;
run;
ods pdf close;
run;
quit;
If you output to rtf, you do not need pdftoc=1 in the 2nd step for ods output, simply like:
proc document name=test;
ods rtf file="after.rtf" toc_data contents=yes;
replay;
run;
ods rtf close;
run;
quit;

Related

Dimension of a picture in a SAS report

How to define the dimensions of an image to be added to a report created in SAS (ods rtf)?
I use the following procedure:
ods graphics on / width=4.5in height=3.5in;
data tt1;
image="&blabla\tt_general.jpg";
output;
run;
proc report data=tt1 noheader nofs style={frame=void rules=none protectspecialchars=off outputwidth=80%} nowindows;
column image;
define image / "" display WIDTH=10 style={cellwidth=18cm};
compute image;
call define( _col_, "Style", "Style=[PREimage='"!!image!!"']");
image="";
endcomp;
run;
Maybe there is a better way to include an image in a report, to define the width and height?
You can place a preimage= style reference in an ods text statement.
Example:
* create some arbitrary image to be shown in rtf;
%let workpath = %sysfunc(pathname(WORK));
ods listing gpath="&workpath";
ods graphics / reset imagename="carbars" outputfmt=jpg;
proc sgplot data=sashelp.cars;
vbar make / group=type;
run;
ods listing close;
ods rtf file="c:\temp\myoutput#%sysfunc(monotonic()).rtf";
ods escapechar = '^';
ods text = "^S={preimage=""&workpath.\carbars.jpg""}"; %* <---- place image in rtf;
ods rtf close;

Organize ODS output by an ID

I need to create 3 graphs for each facility and output these onto 1 page. I have 600 facilities to do this for so I will have a 600 page document. I have created my graphs using the code below. If I specify a "where ID=X" in the proc sgplot statement, it outputs everything fine, but only for facility X. If I don't, it prints Graph 1 for every facility before going to the next graph. I'm guessing I need a macro... does anyone have any advice?
OPTIONS orientation=vertical nodate;
ods rtf file="C:\Users\filename.rtf" STYLE=Styles.rtf;
ods listing close;
ods noproctitle ;
ODS ESCAPECHAR='^';
title ; footnote;
*First graph;
ods graphics on / height=2.7 in width=8in;
ods rtf startpage=NOW;
ods rtf text= "^{style[fontweight=bold fontsize=11pt textalign=c] Employees}";
ods graphics/noborder;
proc sort data=clean4; by ID warehouse county; run;
proc sgplot data=clean4;
by pfi name;
title2 "ID= #byval(ID) ";
title3 "Name: #byval(warehouse) ";
title4 "County: #byval(county) ";
series x=date y=emp / markers markerattrs=(symbol=CircleFilled color=blue) lineattrs=(color=blue thickness=2 pattern=1 ) legendlabel='Number of Employees' dataskin=pressed;
yaxis label='Count' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) offsetmin=0 integer;
xaxis label='Date' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) ;
option NOBYLINE;
run;
*Second graph;
ods graphics on / height=2.7 in width=8in;
ods rtf startpage=NO;
ods rtf text=' ';
ods rtf text= "^{style[fontweight=bold fontsize=12pt textalign=c] Hats used daily}";
ods graphics/noborder;
proc sort data=clean4; by ID; run;
proc sgplot data=clean4;
by ID;
title2; title3;
series x=date y=hats / markers markerattrs=(symbol=CircleFilled color=red)
lineattrs=(color=red thickness=2 pattern=1 ) legendlabel='Number of hats used' dataskin=pressed;
yaxis label='Count' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) fitpolicy=thin
offsetmin=0 integer;
xaxis label='Date' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) ;
run;
*Third graph;
ods graphics on / height=2.7 in width=8in;
ods rtf startpage=NO;
ods rtf text=' ';
ods rtf text= "^{style[fontweight=bold fontsize=11pt textalign=c] LOESS}";
ods graphics/noborder;
proc sort data=clean4; by ID; run;
proc sgplot data=clean4;
by ID;
loess y=var1 x=date/ legendlabel="LOESS" lineattrs=(color=blue)
FILLEDOUTLINEDMARKERS MARKERFILLATTRS=(color=black);
yaxis label='LOESS Plot' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) offsetmin=0;
xaxis label='Date' valueattrs=(size=11pt) labelattrs=(size=11pt weight=bold) THRESHOLDMIN=0
THRESHOLDMAX=0 ;
option NOBYLINE;
run;
ods rtf close;
ods listing ;
Because you are using the same data set clean4 for producing output in three different ways for each ID you need to change only a minimal amount of code when you convert to macro (macroize) the existing code.
Two steps
macroize existing code to operate on a single 'ID' value (the do'er)
run the macro for each ID (the run'er)
Do'er
%macro doReport(ID=);
* move the sort to the top;
* only need to sort the data once (for your situation);
proc sort data=clean4 out=clean4_oneID;
by ID warehouse county;
where ID = "&ID";
run;
* Place all the graphing code here;
* change all the 'clean4' data set references to 'clean4_oneID';
%mend;
Run'er
* Place ODS RTF and settings here;
* obtain list of each id;
proc sort nodupkey data=clean4 out=id_list; by id; run;
* 'stackingly' invoke macro for each id;
data _null_;
set id_list;
call execute (cats('%nrstr(%doReport(ID=',id,'))');
run;
* stacked execute code will now be submitted by SAS supervisor;
* close the RTF here;

SAS regression result output to excel in one sheet

I want to output my SAS regression result into excel.
The code is:
proc import datafile = 'cmds.csv'
out = Work.cmds
dbms = CSV;
run;
ODS TAGSETS.EXCELXP
file="dt.xls";
STYLE = STATISTICAL;
proc sort data=Work.Cmds out=Work.Cmds;
by year;
run;
proc reg data=Work.Cmds outest=want tableout;
by year;
model Investment = Size Growth_New Leverage complex Deficit pc_income_NEW Density/hcc adjrsq ;
ods output parameterestimates=want2;
run;
ODS TAGSETS.EXCELXP CLOSE;
Although it successfully generates the excel file, it contains many sheets. I want to generate all things in one sheet. How can I do?
There are options within the tagsets, in specific sheet_interval. To have all go to one page, set the sheet interval option to none.
ODS TAGSETS.EXCELXP file="dt.xls" STYLE = STATISTICAL options (sheet_interval='none');
However, TAGSETS.EXCELXP generates an XML file, not an Excel file. If you have SAS 9.4 TS1M4+ then I would recommend ODS EXCEL instead.
ods excel file="dt.xlsx" style=statistical options (sheet_interval = 'none');
List of all options for ODS TAGSETS.EXCELXP is here:
https://support.sas.com/rnd/base/ods/odsmarkup/excelxp_help.html
Full example that will generate a single tab:
ods tagsets.excelxp file='C:\_localdata\demo.xls' options(sheet_interval='none');
proc sort data=sashelp.cars out=cars;
by origin;
run;
proc reg data=cars outest=demo tableout;
by origin;
model mpg_city = mpg_highway invoice cylinders;
ods output parameterEstimates=want;
run;
ods tagsets.excelxp close;

Proc Report - Rows of two tables

I have to export some data in the format of two tables per row, with multiple rows. So far I have got as far as building a report with multiple tables stacked on top of each other, but with only one per row by using multiple proc report statements in a code statement as so:
proc report data = mydata; title 'My Title:'; run;
proc report data = mydata; title 'My Title:'; run;
proc report data = mydata; title 'My Title:'; run;
What do I need to add/amend so that I get two tables per row in my report?
Thanks
Some destinations support this directly in the ODS statement; like ODS PDF.
ods pdf file="test.pdf" columns=2 ;
proc print data=sashelp.class;
run;
proc freq data=sashelp.class;
tables age;
run;
ods pdf close;
However, HTML doesn't. For those you'll want to use ODS LAYOUT.
ods html file="test.html";
ods layout gridded
columns=2;
ods region;
proc print data=sashelp.class;
run;
ods region;
proc freq data=sashelp.class;
tables age;
run;
ods layout end;
ods html close;
See the ODS Layout Tip Sheet for more details.
ODS LAYOUT won't work with ODS EXCEL, sadly. You can use this macro to do something similar, if you prefer, or perhaps use PROC DOCUMENT to get the tables together, but I'm not sure exactly how that would work.
If you want more than one table in each column, then you can either have one ODS REGION per table (they'll end up being alternated l-r-l-r) or you can just add more to the two ODS REGIONs here if you don't need them to be gridded properly.
IE:
ods html file="test.html";
ods layout gridded
columns=2;
ods region;
proc print data=sashelp.class;
run;
ods region;
proc freq data=sashelp.class;
tables age;
run;
ods layout end;
ods html close;
Those just have two columns with 2 tables in each column, but they're not aligned.
ods html file="test.html";
ods layout gridded
columns=2;
ods region;
proc print data=sashelp.class;
run;
ods region;
proc freq data=sashelp.class;
tables age;
run;
ods region;
proc print data=sashelp.cars;
run;
ods region;
proc freq data=sashelp.cars;
tables origin;
run;
ods layout end;
ods html close;
This has a proper grid layout.
I resolved this in the end by tweaking the above as so:
ods layout gridded columns=2 rows=2;
ods region;
proc print data=sashelp.class;
run;
ods region;
proc freq data=sashelp.class;
tables age;
run;
ods region;
proc print data=sashelp.cars;
run;
ods region;
proc freq data=sashelp.cars;
tables origin;
run;
ods layout end;
Obviously, rows and columns will change depending on your needs. This produces a SAS report, that I then exported as a step in the project as a HTML file.
Thanks

Hide 'by' group titles in ODS output

I'm trying to hide the titles for each by group in my ODS output. Code:
ods noproctitle;
ods html ;
proc sort data=sashelp.class out=class;
by sex;
run;
proc freq data=class;
by sex;
tables sex / list;
run;
Specifically, the titles I'm trying to hide are:
Sex=F
and
Sex=M
Look at the BYLINE/NOBYLINE option.
options nobyline;
Here's the documentation reference
http://support.sas.com/documentation/cdl/en/lesysoptsref/69799/HTML/default/viewer.htm#n1hr2wb7h5g6twn1gtt5r4zjsg39.htm