SAS ODS PDF title page 2 - pdf

I am somehow failing to get a title to display on the second page of a SAS PDF output. My code (as far as the title statements are concerned) is nearly identical to a previous program I wrote that works perfectly. Page 1 works exactly as intended but page 2 displays no title at all despite my various efforts. Code that I believe should work is below. I took out most of the actual info to make it easier to read, but for some reason if anything inside the proc report or proc sgplot could be affecting the title on the page then let me know and I can share more. Thanks for the help.
ods pdf file="location/name";
footnote "footnote";
ods escapechar='^';
ods pdf startpage=now;
options orientation=portrait nodate;
title1 '^S={Preimage="image"}';
title2 height=12pt bold 'Page 1 title' ;
proc report data= data1
/*variables and stuff*/
run;
ods pdf startpage = no;
proc report data= data2
/*variables and stuff*/
run;
ods pdf startpage=no;
proc report data=data3
/*variables and stuff*/
run;
ods pdf startpage=no;
proc report data=data4
/*variables and stuff*/
run;
title1;
title2;
*****Page 2;
ods pdf startpage=now;
options orientation=portrait;
title3 'Page 2 Title';
proc sgplot data=data5;
/*variables and stuff*/
run;
ods pdf startpage=no;
proc sgplot data=data6 ;
/*variables and stuff*/
run;
title3;
ods pdf close;

I don't believe it's possible to change the titles that way - titles in PDF are more like PDF-level.
Looking at this question on SAS Communities, I think the best way to solve this is to use ODS TEXT which lets you put arbitrary text on the page.
--
Edit: Reeza has it right; this is very much possible, as long as each page has a new Proc on it. Just make sure NOGTITLE so the grahpics aren't swallowing your titles.

Specify the NOGTITLE option. Your second page is all graphics and the titles are getting embedded in the graphics heading (in the picture) rather than being passed to the PDF file. FYI - it's a good practice to have a single ODS PDF statement rather than multiple statements to set options as you can then overwrite previous settings.
This works for me.
ods pdf file="/home/fkhurshed/Demo1/test.pdf" startpage=now;
footnote "footnote";
ods escapechar='^';
options orientation=portrait nodate;
title1 'Dummy Title';
title2 height=12pt bold 'Page 1 title' ;
proc report data= sashelp.class (obs=2);
/*variables and stuff*/
/*variables and stuff*/
run;
ods pdf startpage = no;
proc report data= sashelp.class (obs=4);
/*variables and stuff*/
/*variables and stuff*/
run;
ods pdf startpage=no;
proc report data=sashelp.class (obs=3);
/*variables and stuff*/
run;
ods pdf startpage=no;
proc report data=sashelp.class (obs=2) ;
/*variables and stuff*/
run;
*****Page 2;
ods pdf startpage=now gtitle;
options orientation=portrait;
title1 'Page 2 Title';
proc sgplot data=sashelp.stocks ;
where stock = "IBM";
series x=date y=high;
run;
ods pdf startpage=no;
proc sgplot data=sashelp.stocks ;
where stock = "IBM";
series x=date y=high;
run;
title3;
ods pdf close;

Related

How to add response option labels in SAS data set from an excel file

I have a SAS data set which just has the variable names for each variable:
Separately, I have two CSV files - one that contains the variable label (file is in 'long format'):
and one that contains the response option labels (also in 'long format'):
I would like to apply the variable labels and response option labels to my SAS data set. I imagine uploading my CSV files to SAS, to make data sets, but then after that, I am not sure how to proceed. It seems that Proc datasets may be an option, but I have not been able to find an example that I could figure out to apply to my scenario.
Any help - as always - is much appreciated.
Best,
Camilla
See if you can use this as a template. I can only see educatio in your response option labels, but do the same format trick for the variables of interest.
Feel free to ask.
/* Sample data */
data have;
input gender s_5 p_gender s_6 p_age rellengt educatio;
infile datalines dlm = ',';
datalines;
1, , 1, , 66, 25, 4
0, , 1, , 78, 46, 6
1, , 0, , 72, 50, 4
;
data val_labels;
input var $ 1-8 label $ 10 - 74;
infile datalines missover;
datalines;
gender Hvad er dit køn:
s_5 Hvad er dit køn: - Andet
p_gender Er du i et fast parforhold med en mand eller en kvinde?
s_6 Er du i et fast parforhold med en mand eller en kvinde? - Andet
p_age Hvad er din partners alder (i år)?
rellengt Hvor længe har du og din partner været sammen?
educatio Hvad er dit højest fuldførte uddannelsesniveau?
;
data res_labels;
input var $ 1-8 value 10 label $ 12 - 63;
infile datalines missover;
datalines;
educatio 1 Grundskode til og med 6. klasse
educatio 2 Grundskole 7-10. klasse / forberedende uddannelse
educatio 3 Gymnasiel uddannelse
educatio 4 Erhvervsfaglig uddannelse
educatio 5 Kort videregående uddannelse
educatio 6 Mellemlang videregående uddannelse
educatio 7 Lang videregående uddannelse
educatio 8 Ph.D / Forskeruddannelse
;
/* Variable Labels */
proc sql noprint;
select compbl(cats(var, '=', quote(label)))
into :label separeted by ' '
from val_labels
;
quit;
proc datasets lib = work nolist;
modify have;
label &label.;
quit;
proc contents data = have;
run;
/* response format */
data fmt;
set res_labels(rename=(value=start label=label)) end=eof;
retain fmtname "edufmt" type "n";
output;
if eof then do;
start=""; Label="";
HLO="O"; output;
end;
run;
proc format library = work cntlin = fmt;
run;
data want;
set have;
format educatio edufmt.;
run;
proc print data = want;
run;

SAS ods pdf footnote on 2 lines

I would like to output a SAS result in a pdf file. In the footnote, I would like to have 2 lines on the right bottom of the page:
Doc Research
Page 1 of 10
Here is an example:
options nodate nonumber;
data work.animals;
input name $ weight;
datalines;
monkey 20
shark 500
lion 200
wolf 120
buffalo 400
;
run;
ods pdf file = 'C:\sasdata\animals.pdf';
ods escapechar= '!';
proc print data=work.animals;
title 'Animals';
footnote j = r 'Page !{thispage} of !{lastpage}';
run;
ods pdf close;
ods listing;
Use this:
footnote j = r "Doc Research !{newline} Page !{thispage} of !{lastpage}";

SAS - pdf output with changed bookmarks

My problem is as follows - I have two datasets, out of which I create through macro loop 2 * 2 graphs. I plot these two graphs into the pdf file having the first 2 graphs on the page 1 and the other graphs on the page 2.
The output pdf is fine, the only thing I would like to change are bookmarks. I would like them to contain some detailed information about the graphs - one separate original bookmark per each graph.
Is there some simple way how to do that ? I have found out some complicated solutions through proc report, but is there any easy way for my current code ?
data out_i_a; set sashelp.retail; run;
data out_ii_b; set sashelp.retail; run;
data y;
length saz tef $100;
input saz $ tef $;
datalines;
i a
ii b
;
run;
%macro grafy();
proc sql;
select count(*) into: pocet from y;
quit;
ods _all_ close;
goptions hsize=20cm vsize=8cm;
ods pdf file="\\srv05\nt05a\GRAF\TOT_testing.pdf";
ods layout gridded columns=1;
%do i=1 %to &pocet;
data _null_;
set y (obs=&i);
call symput("saz" ,strip(saz));
call symput("tef" ,strip(tef));
run;
ods region;
ods pdf text="&saz._&tef";
symbol1 interpol=join height=10pt VALUE=NONE LINE=1 WIDTH=1 CV= _STYLE_;
symbol2 interpol=join height=10pt VALUE=NONE LINE=1 WIDTH=1 CV= _STYLE_;
Legend1 value=('SALES' 'YEAR');
axis1 label=('# sales');
axis3 label=('# year');
axis2 label=('date');
proc gplot data= out_&saz._&tef;
plot (SALES)*DATE / overlay skipmiss
VAXIS=AXIS1
HAXIS=AXIS2 LEGEND=Legend1;
plot2 (YEAR)*DATE / overlay skipmiss
VAXIS=AXIS3
HAXIS=AXIS2 LEGEND=Legend1;
run;
ods region;
symbol1 interpol=join height=10pt VALUE=NONE LINE=1 WIDTH=1 CV= _STYLE_;
symbol2 interpol=join height=10pt VALUE=NONE LINE=1 WIDTH=2 CV= _STYLE_;
Legend1 value=('year' 'month');
axis1 label=('in %, p.a.');
axis2 label=('date');
proc gplot data= out_&saz._&tef;
plot (YEAR MONTH)*DATE / overlay skipmiss
VAXIS=AXIS1
HAXIS=AXIS2 LEGEND=Legend1;
run;
%end;
ods layout end;
ods pdf close;
%mend;
%grafy();
The current bookmarks - to be changed - are created automatically and are as follows:
The GPlot Procedure - Plot of YEAR by DATE
The GPlot Procedure - Plot of MONTH by DATE
The GPlot Procedure - Plot of YEAR by DATE
The GPlot Procedure - Plot of MONTH by DATE
Before each Proc GPLOT you can issue an ODS PROCLABEL statement to replace the default text shown in the bookmarks top level.
Add / description= to each PLOT statement to specify the bookmark second level text.
For example:
ODS PROCLABEL "&saz &tef SALES"; /* ADD THIS */
proc gplot data= out_&saz._&tef;
plot (SALES)*DATE / overlay skipmiss
DESCRIPTION = "by Date" /* ADD THIS */
VAXIS=AXIS1
HAXIS=AXIS2 LEGEND=Legend1;
plot2 (YEAR)*DATE / overlay skipmiss
VAXIS=AXIS3
HAXIS=AXIS2 LEGEND=Legend1;

sas macro to pull data from multiple files

I'm trying to import data from 15 different txt files into sas. I want to feed the different file names into an array and then use the array elements inside a macro to bring in all the data into the work folder. The following did not work; any help is much appreciated !!
%macro DATAIMP;
array filenames(3) visit visit_event department
%do i =1 %to 3 %by 1
proc import
datafile="C:\Users\AR\Documents\data\&filename(i).txt"
OUT= &filenames(i)_1
dbms=dlm replace;
delimiter=";";
getnames=yes;
run;
end;
%mend DATAIMP;
%DATAIMP;
run;
array is a statemenet within a data step, you cannot use it like that.
What you can do is create a data set containing all your file names and create macro variables from that:
data file;
input filename $50.;
datalines;
visit
visit_event
department
;
run;
%macro DATAIMP;
data _NULL_; /*local macro variables called FILENAME1, FILENAME2,...*/
set file end=fine;
call symput("FILENAME"||compress(_N_),filename);
if fine then call symput("NF",compress(_N_));
run;
%DO I=1 %TO &NF;
proc import
datafile="C:\Users\AR\Documents\data\&&FILENAME&I...txt"
OUT= &&FILENAME&I.._1
dbms=dlm replace;
delimiter=";";
getnames=yes;
run;
%END;
%mend DATAIMP;
%DATAIMP;
Remember that && resolves to & and for each macro resolution you need a . to mark the end of the macro variable.

loop to conditionally export tables SAS (Large number of Variables)

So I am trying to break up a large dataset (70,000 obs with 1,790 variables) based on a specific variable grouping. Excel or CSV is the ideal format to export to, but there is a limitation on variable numbers (260 or something). Any ideas how I can do this in SAS (or R / SQL otherwise)?
I know the macro works, I have used it before. The error message reads the limit on variables has been reached.
There is certainly a limit on creating an Excel file, but not a CSV file. Here is an example using a dummy SAS data set:
data a;
array x(*) x1-x1790;
do j=1 to 5;
do i=1 to dim(x);
x(i) = ranuni(0);
end;
output;
end;
run;
proc export data=a
outfile="c:\temp\tempfile.csv"
dbms=CSV
replace;
run;
And here is the relevant log:
NOTE: The file 'c:\temp\tempfile.csv' is:
Filename=c:\temp\tempfile.csv,
RECFM=V,LRECL=32767,File Size (bytes)=0,
Last Modified=23Jan2013:15:27:13,
Create Time=23Jan2013:15:27:13
NOTE: 6 records were written to the file 'c:\temp\tempfile.csv'.
The minimum record length was 9636.
The maximum record length was 23087.
NOTE: There were 5 observations read from the data set WORK.A.
NOTE: DATA statement used (Total process time):
real time 0.26 seconds
cpu time 0.09 seconds
5 records created in c:\temp\tempfile.csv from A.
NOTE: "c:\temp\tempfile.csv" file was successfully created.
NOTE: PROCEDURE EXPORT used (Total process time):
real time 2.04 seconds
cpu time 0.26 seconds
Note the first row contains column headers.
UPDATE: If you have a recent version of SAS (9.3 TS1M1 or later) you can create an Office 2010 Excel spreadsheet, which has a maximum of 1,048,576 rows by 16,384 columns. In that case, you would use DBMS=XLSX.
Bob's answer is good if you are okay with XLSX or a CSV. If you do want to make a .xls excel file (255 column limit), or don't have 9.3TS1M1, it's fairly easy to do that. How exactly depends on how you want to specify the columns that go into each file.
Say you just want each 255 columns into a separate file, and two files split at the midpoint (35000 records into file A, 35001-end into file B, per set of variables). You would do something like this:
options mprint symbolgen;
data test;
array xs x1-x1700;
do id = 1 to 70000;
do _t = 1 to dim(xs);
xs[_t]=ranuni(7);
end;
output;
end;
run;
%macro export_file(varstart=,varend=,varnumstart=0,varnumend=0,recstart=1,recend=0,keeplist=,dset=, libname=WORK, outfile=,sheet="sheet1");
%if &varnumstart ne 0 %then %do;
proc sql noprint;
select name into :varstart from dictionary.columns
where libname=upcase("&libname.") and memname=upcase("&dset.") and varnum=&varnumstart.;
select name into :varend from dictionary.columns
where libname=upcase("&libname.") and memname=upcase("&dset.") and varnum=&varnumend.;
quit;
%end;
%if &varstart=%str() or &varend=%str() %then %do;
%put "ERROR: MISSING PARAMETERS. PLEASE CHECK YOUR MACRO CALL AND RERUN. MUST HAVE VARSTART AND VAREND OR VARNUMSTART AND VARNUMEND.";
%abort;
%end;
data _for_Export/view=_for_export;
set &libname..&dset;
keep &varstart.--&varend.
%if &keeplist ne %str() %then %do;
&keeplist
%end;
;
if _N_ ge &recstart.;
%if &recend ne 0 %then %do;
if _N_ le &recend.;
%end;
run;
proc export data=_for_export file=&outfile. dbms=excel replace;
sheet=&sheet.;
run;
proc datasets nolist noprint lib=work;
delete _for_export/memtype=view;
quit;
%mend export_file;
%export_file(varnumstart=1,varnumend=250, keeplist=id,recstart=1,recend=35000,dset=test,outfile="c:\temp\test.xls",sheet="sheet1");
%export_file(varnumstart=1,varnumend=250, keeplist=id,recstart=35001,recend=99999,dset=test,outfile="c:\temp\test.xls",sheet="sheet2");
%export_file(varnumstart=251,varnumend=500, keeplist=id,recstart=1,recend=35000,dset=test,outfile="c:\temp\test.xls",sheet="sheet3");
%export_file(varnumstart=251,varnumend=500, keeplist=id,recstart=35001,recend=99999,dset=test,outfile="c:\temp\test.xls",sheet="sheet4");
Mine fails when I try to export sheet4, not sure if there's some limit to the total size of an .xls file, but you can easily modify this to create separate files. This wouldn't work if you needed to specify specific variable names that are nonconsecutive for each separate file, but you could fairly easily modify the SQL code that pulls from dictionary.columns to instead pull from a table you create that holds the variable names you want in each file.