Order ODS Output by Variable Not in Graph - sas

I am using ODS to output an rtf file with graphs for each warehouse, using the warehouse ID as the by value. I need to organize the graphs in ascending order of rejected products per 100 produced. I was reordering the graphs manually in Word, but now I am being asked to produce this for the top 20 warehouses instead of the top 5 and would prefer not to do this manually. I've created a variable (norder) to indicate the ranking of each warehouse, but if I sort by this or try to use it as a by value, it messes up the graphs. I have also tried the NOTSORTED option, but this did not work. Is there an easy way to do this? Below is my code:
proc transpose data=WIDE_war
out=Long_war(rename=(Col1=Value))
name=source;
by norder ID name county zipcode date;
var defect1 defect2;
run;
proc sort data=long_war; by ID name zipcode county; run;
OPTIONS orientation=landscape nodate;
ods rtf file="C:\Users\....Top_10_Warehouse.rtf" STYLE=Styles.rtf bodytitle STARTPAGE=NO;;
ods listing close;
ods noproctitle ;
ODS ESCAPECHAR='^';
title; footnote;
title;
ods graphics on / height=7in width=9in;
ods graphics/noborder;
/*Table*/
/*List name, ID, number of products produced, number of defects, the rate of defects per 100 units produced */
/*sort by descending order of the last number */
ods rtf text= "^{style[fontweight=bold just=c fontsize=14pt]Warehouses with the greatest number of defects per 100 units produced}";
proc sort data=req4; by descending rejrat2; run;
proc print data=req4 noobs label;
var ID name ZIPcode County;
var mean_prod newdefects rejrat2 /style(data)={ width=1in};
run;
* time trend plots;
ods rtf startpage=NOW;
ods rtf text= "^{style[fontweight=bold just=c fontsize=14pt] Trend plot of the warehouses listed in the above table since June 01, 2020}";
proc sgplot data=long_war;
by ID name county ;
title1 "ID= #byval(ID) ";
title2 "Name: #byval(name) ";
title3 "County: #byval(county) ";
vbar date/ response=Value group=source groupdisplay=stack grouporder=data NOOUTLINE;
xaxis type=linear thresholdmin=0 label="Date"
values=('01jun20'd to '13dec20'd by 7)
labelattrs=(size=12pt weight=bold)
valueattrs=(size=13pt);
yaxis min=0 label="Count" INTEGER grid
labelattrs=(size=12pt weight=bold)
values=(0 to 35 by 5)
valueattrs=(size=13pt) fitpolicy=thin offsetmin=0 ;
label Source = "Defects by type"
Value = "Count";
options NOBYLINE;
run;
ods rtf close;
ods listing ;

Related

Overlay the average trend on group by trends using Proc sgplot

I want to create a line graph that includes the overall trend of a disease rate and the specific trends for males and females. I use the following code for to create the group by trends. How to add he average trend to this line graph. Thanks for your help.
proc sgplot data=have ;
vline year/response=disease_rate group=sex stat=mean datalabel=disease_rate ;
yaxis values=(0,1) label="Percentage";
run;
Here's an example of summarizing it and then displaying it on the graph. There are more than one way to do this though, this is just one.
data have;
set sashelp.heart(in=a);
year=round(2021-ageAtStart, 10);
disease_rate= status="Dead";
run;
proc means data=have mean noprint;
class sex year;
types sex sex*year;
var disease_rate;
output out=summary_stats mean=average_value;
run;
proc sort data=summary_stats;
by sex year;
run;
data graph_data;
merge summary_stats(where=(_type_=2) rename=average_value=mean_sex_year)
summary_stats(where=(_type_=3) rename=average_value = mean_sex);
by sex;
format mean_sex: percent12.1;
run;
proc sgplot data=graph_data ;
*where year > 1990;
vline year/response=mean_sex_year group=sex stat=mean datalabel=mean_sex_year ;
vline year/response=mean_sex group=sex stat=mean datalabel=mean_sex ;
run;
Use series instead of vline so that you can overlay a regression on top of it to get an average trend line. For example:
proc sql;
create table have as
select date
, region
, sum(sale) as sale
from sashelp.pricedata
group by region, date
order by region, date
;
quit;
proc sgplot data=have;
series x=date y=sale / group=region;
reg x=date y=sale / group=region;
xaxis fitpolicy=rotatethin;
run;

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;

SAS PROC Document - Giving Requested function is not supported when creating HTML page

Created test using PROC DOCUMENT as below:
ods listing ;
ods document name=test(write);
proc report data=sashelp.prdsal3 contents=' Country wise Product and Actual SALE';
columns country product actual ;
define country / display;
define product / display ;
run;
ods proctitle=on;
title 'This is a simple PROC TABULATE procedure';
proc tabulate data=sashelp.prdsal3 ;
class country product ;
var actual;
table country * product , actual / contents='SALE actuals';
run;
ods document close;
ods listing;
proc document name=test;
list / levels=all;
run;
ods listing close;
Here is the listing:
ods listing;
proc document name=test;
list / levels=all;
run;
ods listing close;
Listing of: \Work.Test\
Order by: Insertion
Number of levels: All
Obs Type
1 Dir
2 \Report#1 Dir
3 \Report#1Report#\Report#1 Table
4 Dir
5 \Tabulate#1Report#1 Dir
6 \Tabulate#1\Report#1Table#1 Table
Getting error with this code:
ods html file='c:\documents and settings\ANA\Output\ODS_contents_TEST.html';
proc document name=test;
replay ;
run;
ods html close;
NOTE: PROCEDURE DOCUMENT used (Total process time):
real time 24.64 seconds
cpu time 0.06 seconds
432 proc document name=test;
433 replay ;
434 run;
ERROR: Requested function is not supported.
435 ods html close;
NOTE: Remote submit to WINDOWS complete.
What could be the problem

BY-variable not shown in Univariate Frequencies?

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.