Hi All
I have these forestplots and the top 'overall' coloum header is being cut off halfway as you can see every other page.
Please can you have a look at my code why this may be? 😕
Makes no sense as you why it is happening every other page when the code is exactly the same!
CODE;
***graphing macro***;
%macro fplt (datin=, FN=, VZT=, chrt=, wht=, ftnx=);
proc datasets library=work Nolist; delete inxdat:; run; quit;
data inxdat01; set &datin.; where AVISITN=&VZT.; run;
%macro skip; *set up the template*;
**
* Forest plot template using a one-column outermost lattice layout.
* The header uses a nested lattice layout in the top side bar.
* An overlay layout makes up the main area below it.
* The left side table of values are axis tables placed inside
* inner margin of the overlay layout.
**; %mend skip;
proc sql;
create table inxdat02 as
select min(Lower) as mxlow,
max(Upper) as mxupp
from inxdat01;
quit;
%if &ftnx. ne EQIX %then %do;
data inxdat03;
set inxdat02;
rlow=(floor((mxlow/10)))*10;
rupp=(ceil((mxupp/10)))*10;
run;
proc sql noprint;
select rlow format=4. into:lowval trimmed from inxdat03;
select rupp format=4. into:uppval trimmed from inxdat03;
select Estimate format=8.4 into:reflx from inxdat01 where SubGroup='Overall';
quit;
%end;
%if &ftnx. = EQIX %then %do;
data inxdat03;
set inxdat02;
rlow=(floor((mxlow*10)))/10;
rupp=(ceil((mxupp*10)))/10;
run;
proc sql noprint;
select rlow format=4.1 into:lowval trimmed from inxdat03;
select rupp format=4.1 into:uppval trimmed from inxdat03;
select Estimate format=8.4 into:reflx from inxdat01 where SubGroup='Overall';
quit;
%end;
ods path(prepend) work.templat(update);
proc template;
define statgraph forestAxisTable;
dynamic _bandColor _headerColor;
begingraph ;
discreteattrmap name='text' / trimleading=true;
value '1' / textAttrs=(size=7 weight=bold);
value '2' / textAttrs=(color=gray size=6 weight=normal);
enddiscreteattrmap;
discreteattrvar attrvar=txtDAV var=id attrmap='text';
layout lattice / columns=1;
*--Column headers--*;
sidebar / align=top;
layout lattice / columns=2 columnweights=(0.55 0.45)
backgroundcolor=_headerColor opaque=true;
entry textAttrs=(size=8 weight=bold) hAlign=left "Subgroup"
hAlign=right " No. of Patients";
entry textAttrs=(size=8 weight=bold) hAlign=center "LS Mean Change from Baseline";
endLayout;
endsidebar;
* Single cell with inner margins for left and right tables *;
layout overlay / xAxisOpts=(display=(line ticks tickvalues)
tickValueAttrs=(size=6 weight=bold)
labelAttrs=(size=6 weight=bold)
linearOpts=(tickValuePriority=true
%if &ftnx. ne EQIX %then %do;
tickValueSequence=(start=&lowval. end=&uppval. increment=10)
%end;
%if &ftnx. = EQIX %then %do;
tickValueSequence=(start=&lowval. end=&uppval. increment=.1)
%end;
)
offsetMin=0.1
)
yAxisOpts=(reverse=true display=none offsetMin=0) wallDisplay=none;
* Left-side table *;
innerMargin / align=left;
axisTable y=obsId value=subGroup / textGroup=txtDAV
indentWeight=indentwt ; *display=(values)*;
axisTable y=obsId value=mdl_n_c / ; *display=(values)*;
endInnerMargin;
* LS Means plot *
referenceLine y=ref / lineAttrs=(thickness=15 color=_bandColor);
scatterPlot y=obsId x=Estimate / markerAttrs=(symbol=squareFilled)
xErrorLower=Lower xErrorUpper=Upper errorBarCapShape=none;
referenceLine x=&reflx.;
endLayout; * overlay *;
endLayout; * lattice *;
endgraph;
end;
run;
%macro skip; *forest plot graphing*; %mend skip;
proc sgrender data=inxdat01 template=forestAxisTable;
dynamic _bandColor='cxf0f0f0' _headerColor='cxd0d0d0';
title1 f='Courier' h=9pt " ";
footnote1 f='Courier' h=8pt j=l " ";
%if %upcase(%substr(&ftnx, 1, 4)) eq QLQS %then %do;
footnote2 f='Courier' h=8pt j=l " ";
%end;
%if %upcase(%substr(&ftnx, 1, 4)) eq QLQF %then %do;
footnote2 f='Courier' h=8pt j=l " ";
%end;
%if %upcase(%substr(&ftnx, 1, 4)) eq EQVA %then %do;
footnote2 f='Courier' h=8pt j=l " ";
%end;
%if %upcase(%substr(&ftnx, 1, 4)) eq EQIX %then %do;
footnote2 f='Courier' h=8pt j=l " ";
%end;
&runlinea.;
run;
quit;
%mend fplt;
ods _all_ close;
*ods listing image_dpi=300;
ods graphics / reset width=6in height=5.5in imagename='SAS94M2_ForestPlot_GTL';
OPTIONS LEFTMARGIN=1.0in RIGHTMARGIN=1.0in TOPMARGIN=1.0in BOTTOMMARGIN=1.0in
FORMCHAR = '|----|+|---+=|-/<>*' nonumber nodate nocenter orientation=landscape;
ODS escapechar='^';
goptions reset=all;
goptions ftext="Courier";
*ods pdf file="&dirty.\test.pdf";
ods pdf file="x ";
***************************;
** COHORT A **;
*************************;
%fplt (datin=Fp01_1_1_1, FN=4.1.1.1.1, VZT=9, chrt=A, wht=xxxxxx, ftnx=QLQS);
%fplt (datin=Fp01_1_1_1, FN=4.1.1.1.2, VZT=17, chrt=A, wht=xxxxx, ftnx=QLQS);
%fplt (datin=Fp01_1_1_1, FN=4.1.1.1.3, VZT=25, chrt=A, wht=xxxxx, ftnx=QLQS);
%fplt (datin=Fp01_1_1_1, FN=4.1.1.1.4, VZT=33, chrt=A, wht=xxxxxx, ftnx=QLQS);
ods pdf close;
Any suggestions will be appreciated!
Thanks
Found a solution it seems!
by changing or deleting the y axis option offsetMin
yAxisOpts=(reverse=true display=none /*offsetMin=0*/ ) wallDisplay=none;
Its has worked and the top colum is not being cut off anymore 🙂
Hi,
Well, I don't have timme to debug all that. What I would say from looking at the pages is that I guess each two pages are blocks from one set of output procedures. As no page breaking is given, it will just flow over to the next page. I would put a hard break in after each block (in our cases we also put a preceding blank row before and after the block to separate headings from data).
Hi,
Well, I don't have timme to debug all that. What I would say from looking at the pages is that I guess each two pages are blocks from one set of output procedures. As no page breaking is given, it will just flow over to the next page. I would put a hard break in after each block (in our cases we also put a preceding blank row before and after the block to separate headings from data).
Hi RW9
Thanks.. How & where would I put in the hard break? would it be an ods start page=yes type thing?
..
The simplest way would be to split the outpu in the macro call, so page 1 is output by one call to render, then page 2 is created by another call. That way each will appear on their own pages. Without going through its hard to place where hard page breaks would be added.
Found a solution it seems!
by changing or deleting the y axis option offsetMin
yAxisOpts=(reverse=true display=none /*offsetMin=0*/ ) wallDisplay=none;
Its has worked and the top colum is not being cut off anymore 🙂
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.