Issue: I'm running in the same code two separate proc tabulate which generate two seaparate cross frequency tables. I would be able to generate two different result reports as output instead of the standard one aggregating the two outputs in the same result page, without the need to create two separate codes. There is any method to achive this?
Update1 : Below is the output of the two proc tabulate I want separate into two differente objects.
enter image description here
You can use the SAS ODS (Output Delivery System) and output your results to two different files. (the file can be a pdf, html, rtf).
Code below based on SAS Support Example will split the output into two files ttest1.htm & ttest2.htm
title 'Comparing Group Means';
data Scores;
input Gender $ Score ##;
datalines;
f 75 f 76 f 80 f 77 f 80 f 77 f 73
m 82 m 80 m 85 m 85 m 78 m 87 m 82
;
ods html body='ttest1.htm' style=HTMLBlue;
proc ttest;
class Gender;
var Score;
run;
ods html close;
ods html body='ttest2.htm' style=HTMLBlue;
proc ttest;
class Gender;
var Score;
run;
ods html close;
In SAS Enterprise Guide:
You can add the option to create your SAS report output in RTF and PDF formats. This will show the page break in one file/report.
Go to Tools/Options then check the output formats you want and re-run your project.
Related
I want to use SAS and eg. proc report to produce a custom table within my workflow.
Why: Prior, I used proc export (dbms=excel) and did some very basic stats by hand and copied pasted to an excel sheet to complete the report. Recently, I've started to use ODS excel to print all the relevant data to excel sheets but since ODS excel would always overwrite the whole excel workbook (and hence also the handcrafted stats) I now want to streamline the process.
The task itself is actually very straightforward. We have some information about IDs, age, and registration, so something like this:
data test;
input ID $ AGE CENTER $;
datalines;
111 23 A
. 27 B
311 40 C
131 18 A
. 64 A
;
run;
The goal is to produce a table report which should look like this structure-wise:
ID NO-ID Total
Count 3 2 5
Age (mean) 27 45.5 34.4
Count by Center:
A 2 1 3
B 0 1 1
A 1 0 1
It seems, proc report only takes variables as columns but not a subsetted data set (ID NE .; ID =''). Of course I could just produce three reports with three subsetted data sets and print them all separately but I hope there is a way to put this in one table.
Is proc report the right tool for this and if so how should I proceed? Or is it better to use proc tabulate or proc template or...?
I found a way to achieve an almost match to what I wanted. First if all, I had to introduce a new variable vID (valid ID, 0 not valid, 1 valid) in the data set, like so:
data test;
input ID $ AGE CENTER $;
if ID = '' then vID = 0;
else vID = 1;
datalines;
111 23 A
. 27 B
311 40 C
131 18 A
. 64 A
;
run;
After this I was able to use proc tabulate as suggested by #Reeza in the comments to build a table which pretty much resembles what I initially aimed for:
proc tabulate data = test;
class vID Center;
var age;
keylabel N = 'Count';
table N age*mean Center*N, vID ALL;
run;
Still, I wonder if there is a way without introducing the new variable at all and just use the SAS counters for missing and non-missing observations.
UPDATE:
#Reeza pointed out to use the proc format to assign a value to missing/non-missing ID data. In combination with the missing option (prints missing values) in proc tabulate this delivers the output without introducing a new variable:
proc format;
value $ id_fmt
' ' = 'No-ID'
other = 'ID'
;
run;
proc tabulate data = test missing;
format ID $id_fmt.;
class ID Center;
var age;
keylabel N = 'Count';
table N age*(mean median) Center*N, (ID=' ') ALL;
run;
ODS EXCEL FILE="/folders/myfolders/Book1.xlsx";
proc sql;
create table FLIGHTS_WEATHER_J AS
select month,Sum(Dep_delay) as Dp_delay_minutes,
AVG(temp) as Avg_Temp,
AVG(dewp) as AVG_DEWP,
AVG(humid) AS AVG_HUMID,
AVG(wind_dir) AS AVG_WIND_DIR,
AVG(wind_speed) AS AVG_WIND_SPEED,
AVG(wind_gust) AS WIND_GUST,
AVG(precip) AS AVG_PRECIP,
AVG(Pressure_N) AS AVG_PRESSURE,
AVG(visib) AS AVG_VISIB
from C1.FLIGHTS_WEATHER_8
Group by Month;
quit;
RUN;
ODS EXCEL CLOSE;
the log has no errors, still i find only blank output in the excel file
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
NOTE: ODS statements in the SAS Studio environment may disable some output features.
73
74
75 ODS EXCEL FILE="/folders/myfolders/Book1.xlsx";
76
77 proc sql;
78 create table FLIGHTS_WEATHER_J AS
79 select month,Sum(Dep_delay) as Dp_delay_minutes,
80 AVG(temp) as Avg_Temp,
81 AVG(dewp) as AVG_DEWP,
82 AVG(humid) AS AVG_HUMID,
83 AVG(wind_dir) AS AVG_WIND_DIR,
84 AVG(wind_speed) AS AVG_WIND_SPEED,
85 AVG(wind_gust) AS WIND_GUST,
86 AVG(precip) AS AVG_PRECIP,
87 AVG(Pressure_N) AS AVG_PRESSURE,
88 AVG(visib) AS AVG_VISIB
89
90 from C1.FLIGHTS_WEATHER_8
91 Group by Month;
NOTE: Table WORK.FLIGHTS_WEATHER_J created, with 12 rows and 11 columns.
92 quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 2.67 seconds
cpu time 2.52 seconds
93 RUN;
94
95 ODS EXCEL CLOSE;
NOTE: Writing EXCEL file: /folders/myfolders/Book1.xlsx
96
97
98 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
110
results:
The output is blank because you never wrote any output. All you did was create a dataset. Either add something that produces output:
proc print data=FLIGHTS_WEATHER_J ; run;
Or if you don't actually need the dataset then just remove this
create table FLIGHTS_WEATHER_J AS
from your SQL query.
If you just want to write data into an Excel file use a libref instead of ODS.
libname book1 xlsx "/folders/myfolders/Book1.xlsx";
proc sql;
create table BOOK1.FLIGHTS_WEATHER_J AS ...
Your code does not produce any output, proc sql just creates a table, but without output.
Try this (not create table):
ODS EXCEL FILE="/folders/myfolders/Book1.xlsx";
proc sql;
select month,Sum(Dep_delay) as Dp_delay_minutes,
AVG(temp) as Avg_Temp,
AVG(dewp) as AVG_DEWP,
AVG(humid) AS AVG_HUMID,
AVG(wind_dir) AS AVG_WIND_DIR,
AVG(wind_speed) AS AVG_WIND_SPEED,
AVG(wind_gust) AS WIND_GUST,
AVG(precip) AS AVG_PRECIP,
AVG(Pressure_N) AS AVG_PRESSURE,
AVG(visib) AS AVG_VISIB
from C1.FLIGHTS_WEATHER_8
Group by Month;
quit;
RUN;
ODS EXCEL CLOSE;
Because simple case like this is working fine:
data test;
input A B $ C;
datalines;
1 A 3
4 B 6
;
run;
ods excel file='c:\tmp/ff.xlsx';
proc print data=test;run;
ods excel close;
I want to export a dataset into an Excel file from SAS, like shown below:
Claim_id State Suffix Policy Amount
125 CA 231 cyt $58,000.00
458 dd 789 ghu $78,961.00
458 lk 586 lk -$56.00
785 ga 712 js -$89.00
It needs to have a header like such:
"As of [current month name] [current year].', for instance "As of January 2017".
Also if the amount is negative, it needs to show in the red color.
Title with today's Date in Month Name - Year format:
%let today_month = %sysfunc(today(), monname8.);
%let today_year = %sysfunc(today(), year4.);
%put &today_month. &today_year.;
title "As of &today_month. &today_year.";
Setting a column in Excel to a custom format:
/* This line goes into your PROC PRINT or PROC REPORT */
var amount / style(column)={tagattr="format: $#,##0.00_);[Red]($#,##0.00)"};
To tweak the format, in Excel, right click on the cell, go to Format Cells -> Custom, create your format, and paste the string into the "format: "part.
Example with ODS Excel:
data test;
input Claim_id Amount;
datalines;
125 58000
458 78961
458 -56
785 -89
;
run;
%let today_month = %sysfunc(today(), monname8.);
%let today_year = %sysfunc(today(), year4.);
%put &today_month. &today_year.;
ods excel file='output path and file name here.xlsx'
options(embedded_titles="yes");
proc print data=test noobs;
title "As of &today_month. &today_year.";
var claim_id;
var amount
/ style(column)={tagattr="format: $#,##0.00_);[Red]($#,##0.00)"};
run;
ods excel close;
Result:
Note that ODS EXCEL was experimental in 9.4M2 and became production in 9.4M3. To use the older ods tagsets.excelxp, which is XML but appears as an Excel file, simply swap that in for ods excel:
ods tagsets.excelxp file='output path and file name here.xlsx'
options(embedded_titles="yes");;
... code here ...
ods tagsets.excelxp close;
Sources:
http://blogs.sas.com/content/sasdummy/2014/09/21/ods-excel-and-proc-export-xlsx/ https://support.sas.com/resources/papers/proceedings16/SAS5642-2016.pdf http://support.sas.com/resources/papers/proceedings13/366-2013.pdf
Sounds like you should use ODS EXCEL, which ships with SAS 9.4 TS1M2 I believe. That would let you do exactly what you're asking.
If you don't have that version, you might do the same with tagsets.excelxp, though that doesn't create a normal-excel-file-type file; it would be an xml file that might need a further step to process.
I created a format for a variable as follows
proc format;
value now 0=M
1=F
;
run;
and now I apply this to a dataset.
Data X;
set X2;
format Var1 now.;
run;
and I want to export this format using cntlout
proc format library=work cntlout=form; run;
this gives me the list of formats in the library catalog. But doesnot give me the variable name to which it is attached.
How can I create a dataset with list of formats and the attached variables to it?
So I can see which format is linked to what variable.
If you just want to look up the variables in a specific dataset, often PROC CONTENTS is faster than using SASHELP.VCOLUMN or DICTIONARY.TABLES, particularly when there are lots of libraries/datasets defined.
57 proc contents data=x out=myvars(keep=name format) noprint;
58 run;
NOTE: The data set WORK.MYVARS has 1 observations and 2 variables.
59
60 data _null_;
61 set myvars;
62 put _all_;
63 run;
NAME=Var1 FORMAT=NOW _ERROR_=0 _N_=1
NOTE: There were 1 observations read from the data set WORK.MYVARS.
Assuming you want this for a specific library you can use the SASHELP.VCOLUMN dataset. This dataset contains the formats for all variables and you can filter it as desired.
I try to write the labels of each variable to an Excelsheet in SAS. Im using the option DBLABEL=YESwhich allows you to print the labels as column headings in Excel. Unfortunately it seems that my Labels are too long. Does anybody has a solution? Here is the code I m using:
data test;
length a 3.
b 3.
c 3.;
input a b c;
label a = "this label is too long for writing it from sas to excel";
datalines;
18 20 15
25 20 80
63 72 14
run;
libname xls oledb provider="Microsoft.ACE.OLEDB.12.0"
preserve_tab_names=yes preserve_col_names=yes
datasource="f:my workspace\test_9.xls" provider_string="Excel 12.0";
data xls.test (dblabel=yes);
set test;
run;
libname xls clear;
This is ther error I receive.
ERROR: Error binding parameters: Invalid column name: this label is
too long for writing it from sas to excel
Thanks in advance
This doesn't appear to be a problem with proc export instead.
proc export data=test outfile="C:\test.csv" label;
run;