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;
Related
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;
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;
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}";
I wish to drop the columns in a SAS dataset which has a sum less than a particular value. Consider the case below.
Column_A Pred_1 Pred_2 Pred_3 Pred_4 Pred_5
A 1 1 0 1 0
A 0 1 0 1 0
A 0 1 0 1 0
A 0 1 0 1 1
A 0 1 0 0 1
Let us assume that our threshold is 4, so I wish to drop predictors having sum of active observations less than 4, so the output would look like
Column_A Pred_2 Pred_4
A 1 1
A 1 1
A 1 1
A 1 1
A 1 0
Currently I am using a very inefficient method of using multiple transposes to drop the predictors. There are multiple datasets with records > 30,000 so transpose approach is taking time. Would appreciate if anyone has a more efficient solution!
Thanks!
Seems like you could do:
Run PROC MEANS or similar proc to get the sums
Create a macro variable that contains all variables in the dataset with sum < threshhold
Drop those variables
Then no TRANSPOSE or whatever, just regular plain old summarization and drops. Note you should use ODS OUTPUT not the OUT= in PROC MEANS, or else you will have to PROC TRANSPOSE the normal PROC MEANS OUT= dataset.
An example using a trivial dataset:
data have;
array x[20];
do _n_ = 1 to 20;
do _i = 1 to dim(x);
x[_i] = rand('Uniform') < 0.2;
end;
output;
end;
run;
ods output summary=have_sums; *how we get our output;
ods html select none; *stop it from going to results window;
proc means data=have stackodsoutput sum; *stackodsoutput is 9.3+ I believe;
var x1-x20;
run;
ods html select all; *reenable normal html output;
%let threshhold=4; *your threshhold value;
proc sql;
select variable
into :droplist_threshhold separated by ' '
from have_sums
where sum lt &threshhold; *checking if sum is over threshhold;
quit;
data want;
set have;
drop &droplist_threshhold.; *and now, drop them!;
run;
Just use PROC SUMMARY to get the sums. You can then use a data step to generate the list of variable names to drop.
%let threshhold=4;
%let varlist= pred_1 - pred_5;
proc summary data=have ;
var &varlist ;
output out=sum sum= ;
run;
data _null_;
set sum ;
array x &varlist ;
length droplist $500 ;
do i=1 to dim(x);
if x(i) < &threshhold then droplist=catx(' ',droplist,vname(x(i)));
end;
call symputx('droplist',droplist);
run;
You can then use the macro variable to generate a DROP statement or a DROP= dataset option.
drop &droplist;
I'm trying to plot two sets of calculations and compare them over time. The "cohort" variable, derived from coh_asof_yyyymm from original table, were stored in the data set in numeric format (201003 for 2010 March). Now when I plot them by using proc sgplot, 4 quarters of data are crammed together. How do I change the format of this variable in order to product outputs where x-axis should be in interval of quarters?
options nofmterr;
libname backtest "/retail/mortgage/consumer/new";
proc sql;
create table frst_cur as
select
coh_asof_yyyymm as cohort,
sum(annual_default_occurrence* wt)/sum(wt) as dr_ct,
sum(ScorePIT_PD_2013 * wt)/sum(wt) as pd_ct_pit,
sum(ScoreTTC_PD_2013 * wt)/sum(wt) as pd_ct_ttc
from backtest.sample_frst_cur_201312bkts
group by 1;
quit;
proc sgplot data = frst_cur;
series x = cohort y = pd_ct_pit;
series x = cohort y = pd_ct_ttc;
format cohort yyyyqc.;
xaxis label = 'Cohort Date';
yaxis label = 'Defaults';
title 'First Mortgage Current';
run;
If i'm getting it right, i think your date is a number and not a SAS date. It's not unusual, people do store date as integers in their RDBMS tables and when SAS import data from table, it assumes it to be integer rather than date. Check out the below solution code for reference.
data testing_date_integer;
infile datalines missover;
input int_date 8.;
/* creating another variable which would be a SAS date, based on int_date.
we would be converting the integer date to charater and then append
day (01) to the charater and read using YYMMDD8. informat for SAS
to store the character as date
*/
sas_date=input(cats(put(int_date,8.),'01'),yymmdd8.);
format sas_date YYQ8.;
datalines4;
200008
200009
200010
200011
200012
200101
200102
200103
200104
200105
200106
;;;;
run;
proc print data=testing_date_integer;run;
If above code show and solves you problem then i would recommend you to update you PROC SQL Code
proc sql;
create table frst_cur as
select
input(cats(put(coh_asof_yyyymm ,8.),'01'),yymmdd8.) as cohort,
.
.
.
Also, i would recommend updating the format statement for cohort in PROC SGPLOT
proc sgplot data = frst_cur;
.
.
format cohort yyq8.;
Hope this solves your problem.
Using the YYMMn6. informat
data HAVE;
input DATE YYMMn6.;
format date YYQ8.;
datalines;
200008
200009
200010
200011
200012
200101
200102
200103
200104
200105
200106
;
run;
Proc Print Data=HAVE noobs; Run;
data HAVE2;
input coh_asof_yyyymm 8.;
datalines;
200008
200009
200010
200011
200012
200101
200102
200103
200104
200105
200106
;
run;
proc sql;
create table frst_cur as
select
input(put(coh_asof_yyyymm,6.),YYMMn6.) as cohort format=YYQ8.
From HAVE2;
Quit;