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
Related
I am using SAS enterprise guide 7.15.
I want to export several datasets into multiple excel sheets (multiple tables in every sheet).
I'm using ODS and even though i'm setting sheet_interval="none", after two tables it breaks the page, and shoves the next tables to another excel sheet.
this is an example to my code, here it's exporting 2 tables, later I want to add 20 tables more in the same sheet:
%macro table_1;
proc report data=table_1 out=sheet_1 headline split='#' spacing=1 nowd missing
style(summary)={font_weight=bold}
columns
segment
diff
cnt_old
cnt_new
;
compute before _page_/style=[font_size=3 font_weight=bold foreground=white background=Dark Blue];
line "table 1";
line ' ';
line 'Number of Customers';
endcomp;
compute after;
endcomp
run;
%mend table_1;
%macro table_3;
proc report data=table_3 out=sheet_1 headline split='#' spacing=1 nowd missing
style(summary)={font_weight=bold}
columns
FinalRiskRating
diff
cnt_old
cnt_new;
compute before _page_/style=[font_size=3 font_weight=bold foreground=white background=Dark Blue];
line "table 3";
endcomp;
compute after;
endcomp
run;
%mend table_3;
%table_1; %table_3;
%let shk = table_1 + table_3;
ods path work.temptemp(update) sasuser.templat(update) sashelp.tmplmst(read);
ods path show;
Options mprint mlogic symbolgen nobyline;
ods listing close;
%macro b;
%do i=1 %to 2;
%let mshk=%scan(&shk., &i.,+);
/*ods tagsets.excelxp options(SHEET_INTERVAL='NONE' PAGEBREAK="NO" sheet_name="sheet1" ABSOLUTE_COLUMN_WIDTH='8' AUTOFIT_HEIGHT='yes' embed_titles_once = 'yes' embedded_titles='yes');*/
ods tagsets.excelxp options(sheet_interval="none" sheet_name="sheet1" ABSOLUTE_COLUMN_WIDTH='8' AUTOFIT_HEIGHT='yes' embed_titles_once = 'yes' embedded_titles='yes');
%&mshk.;
%end;
%mend b;
ods tagsets.excelxp file="&reportlocation";
%b;
ods tagsets.excelxp close;
ods _all_ close;
;
My suspicion is because you don't specify sheet_interval='none' on the initial ods tagsets.excelxp.
Like yours, the first example has this problem:
ods tagsets.excelxp file="h:\temp\test.xls";
ods tagsets.excelxp options(sheet_interval='none');
proc print data=sashelp.class;
run;
ods tagsets.excelxp options(sheet_interval='none');
proc print data=sashelp.class;
run;
ods tagsets.excelxp close;
But this works as expected:
ods tagsets.excelxp options(sheet_interval='none') file="h:\temp\test.xls";
proc print data=sashelp.class;
run;
proc print data=sashelp.class;
run;
ods tagsets.excelxp close;
Interestingly, if you remove the second one, it still works - so it's not exactly that it's not on the first line, but rather it's the new options statement. I guess that resets it somehow. But in your case there's really no reason not to put any of those details on the initial ods tagsets.excelxp statement.
ODS EXCEL doesn't work that way, it always goes all on one sheet. I'd recommend using that, if you can, in any event.
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;
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
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;
Is it usual that the Univariate Frequencies does not display the BY-variable while Univariate BasicMeasures does show the BY-variable?
In the example below I load in some data and want to show gas prices by zipcode. The output for PROC FREQ shows the BY-variable (zipcode) in the output as does the UNIVARIATE BasicMeasures. But the UNIVARIATE Frequencies is not showing the BY-variable in the output.
Am I doing something wrong? I've even set the templates to default, with the ODS PATH statement, in case the templates got messed up by other code (or other coders using same account).
DATA prices;
INPUT zipcode price;
DATALINES;
90066 3.10
90066 3.17
90066 3.26
98101 2.99
98101 3.06
98101 3.16
;
run;
proc sort;
by zipcode;
run;
ods path sashelp.tmplmst(read) ;
ods pdf file = "gasprices.pdf";
PROC FREQ data = prices;
tables price;
by zipcode;
run;
ods select Frequencies;
PROC UNIVARIATE data = prices freq;
var price;
by zipcode;
run;
ods select BasicMeasures;
PROC UNIVARIATE data = prices;
var price;
by zipcode;
run;
ods pdf close;
You can specify more than one object in the ODS SELECT, so you could pull both tables out of the same PROC FREQ like this:
ods pdf file = "gasprices.pdf";
ods select BasicMeasures Frequencies;
PROC UNIVARIATE data = prices freq;
var price;
by zipcode;
run;
ods pdf close;
I know that doesn't exactly solve your problem, but it looks to me like the BY-variable display just isn't properly linked to the PROC UNIVARIATE frequency tables (e.g., try ODS SELECT Moments - works fine). Might be worth reporting to SAS.