BookmarkSubscribeRSS Feed
SwissC
Obsidian | Level 7

I am producing a PDF graph that contains some entry statements.  However in PDF they seem to get tructation.  The graph prints perfectly using ODS rtf.  But if you look at the drug names in the medians block you can see they are a. truncated and b. the font seems weird (not the same size). Strangely if I use the text select tool in Acrobat viewer I can select and copy&paste the full text, so it is like it is hidden behind something.  Am I missing something?

Annotation 2019-09-25 110317.png

 

 

 

Code is attached in 3 parts (the 2 macros and the program).  I cannot show any data but the dataset consists of

usubjid, months, cnsr, trt01pn.  Trt01pn has values 2 & 3 formatted to "ABCDEFG + abcdefghijkl" and ""abcdefghijkl" respectively.

 

I am using SAS 9.4

 

 

%macro mkmtemplate;

   %global atriskopts bandopts censored censorstr classopts
           graphopts groups insetopts legendopts ntitles stepopts tiplabel
           tips titletext0 titletext1 titletext2 xoptions yoptions srvtble _colr;

   %let yOptions   = label=&_ylabel shortlabel="Survival" LABELFITPOLICY=splitalways LABELSPLITCHAR="#" labelsplitjustify=bottom  
                     linearopts=(viewmin=0 viewmax=1
                                 tickvaluelist=(0 0.2 0.4 0.6 0.8 1) tickvalueFormat= 3.1 );

   %let xOptions   = shortlabel=XNAME offsetmin=.05 linearopts=(viewmax=&_maxtime tickvaluelist=XTICKVALS tickvaluefitpolicy=XTICKVALFITPOL);

   %let Tips       = rolename=(_tip1= ATRISK _tip2=EVENT)
                     tiplabel=(_tip1="Number at Risk" _tip2="Observed Events")
                     tip=(x y _tip1 _tip2);
                     
   %let TipLabel   = tiplabel=(y="Survival Probability");
   %let StepOpts   = ;

   %let Groups     = group=STRATUM index=STRATUMNUM;

   %let BandOpts   = &groups modelname="Survival";

   %let InsetOpts  = autoalign=(TOPRIGHT BOTTOMLEFT BOTTOMRIGHT TOP BOTTOM RIGHT)
                     border=false BackgroundColor=GraphWalls:Color Opaque=true;

   %let LegendOpts = title=&_legtitl location=inside valueattrs=(size=9pt) &InsetOpts;

   %let AtRiskOpts = valueattrs=(size=9pt)  display=(label) ;
   %let ClassOpts  = class=CLASSATRISK colorgroup=CLASSATRISK display=(label);

   %let Censored   = markerattrs=(symbol=circlefilled size=6);
   %let CensorStr  = "Censored";

   %let GraphOpts  = ;

   %LET srvtble    = YES;


   %macro CompileSurvivalTemplates;
      %local outside;
      proc template;
            define statgraph
               Stat.Lifetest.Graphics.ProductLimitSurvival2;
               dynamic NStrata xName plotAtRisk
                  %if %nrbquote(&censored) ne %then plotCensored;
                  plotCL plotHW plotEP labelCL labelHW labelEP maxTime xtickVals
                  xtickValFitPol rowWeights method StratumID classAtRisk 
                  plotTest GroupName Transparency SecondTitle TestName  ;
               BeginGraph %if %nrbquote(&graphopts) ne %then / border=false pad=0 &graphopts;;


                           
                  legenditem  type=marker name="CenLgd" / label=&CensorStr lineattrs=(color=black) markerattrs=(symbol=circlefilled color=black size=6);

        	  layout lattice / rows=2 rowweights=ROWWEIGHTS columndatarange=union rowgutter=10;
         	    cell;
                  layout overlay / xaxisopts=(&xoptions) yaxisopts=(&yoptions);
				      stepplot y=eval(SURVIVAL)  x=TIME / &groups name="Survival" &tips &stepopts;
				      scatterplot y=eval(CENSORED) x=TIME / &groups &tiplabel &censored name="Censored" legendlabel="Censored";
				      MERGEDLEGEND "Survival" "Censored" / across=1 &legendopts ADDITIONALNAMES=("CenLgd");
				      %if %nrbquote(&srvtble) ne %then %do;
				         %SurvivalTable;
				      %end;
                  endlayout;
                endcell;
         		cell;           
            	  layout overlay / walldisplay=none xaxisopts=(display=none &xOptions);
               	    axistable x=TATRISK value=ATRISK / &atriskopts &classopts;;
            	  endlayout;
         		endcell;
      		  endlayout;

               EndGraph;
            end; 
                        
            quit;
      run;
   %mend CompileSurvivalTemplates;



   %macro SurvivalTable;
      %local fmt r i t;
      %let fmt = &_fmt;
      %let r = halign = right;
               layout gridded / columns=1 rows=4 &InsetOpts ;
                     entry halign=center "Median &kmtype in months (95% CI)" / textattrs=GraphData;
               layout gridded / columns=4 &InsetOpts;
                  dynamic PctMedianConfid;
                  %do i = 1 %to 2;
                     %let t = / textattrs=GraphData&i (family="Courier New" size=9pt) ;
                     dynamic StrVal&i  Median&i LowerMedian&i UpperMedian&i;
                     if (&i <= nstrata)
                          entry &r StrVal&i &t;
                        if(Median&i ne .)       entry &r eval(put(Median&i,&fmt)) &t;       else entry &r "N.E" &t; endif;
                        if(LowerMedian&i ne .)  entry &r "(" eval(put(LowerMedian&i,&fmt)) "," &t;  else entry &r "N.E" &t; endif; 
                        if(UpperMedian&i ne .)  entry &r eval(put(UpperMedian&i,&fmt))")" &t;  else entry &r "N.E" &t; endif;
                     endif;
                  %end;                             
               endlayout;          
               endlayout;
   %mend SurvivalTable;


%CompileSurvivalTemplates;

%mend mkmtemplate;
%MACRO mkmplot (_inds=,
                _time=,
                _cen =,
                _strat=,
                _timetick=,
                _maxtime=,
                _ylabel="Probability of Survival (%)",
                _legtitl=GROUPNAME,
                _alphaqt=0.05,
                _fmt=bestd6.,
                _kmtime=,
                _opts=none,
                _opts2=none,
                _orint=portrait,
                _colour=no,
                _showtxt=1,
                _dev=svg
                );


*******************************************************************************************************/;
*****  Find graph limits and by var label and number of strata                                    *****/;
*******************************************************************************************************/;
PROC CONTENTS data=&_inds out=datatest noprint;RUN;
%LET _strata=;
%LET _xtlbl= - &_strat;
DATA _null_;
  SET datatest (where=(upcase(name)=upcase(compress("&_strat","_", "kna")))); 
  call symput('_strata', "&_strat");
  call symput('_xtlbl', "");
RUN;
PROC DATASETS lib=work memtype=data nolist;DELETE datatest;RUN;QUIT;


PROC SQL noprint;
  %IF %nrbquote(&_maxtime) ne %THEN %DO;
  SELECT distinct ceil(&_maxtime./&_timetick.)* &_timetick.
  INTO :__maxmon
  FROM &_inds;
  %END;

  %ELSE %DO;
  SELECT distinct ceil(max(&_time)/&_timetick.)* &_timetick.
  INTO :__maxmon
  FROM &_inds;
  %END;
QUIT;


*******************************************************************************************************/;
*****  Run template and make any required updateds                                                *****/;
*******************************************************************************************************/;

%mkmtemplate;

/* make changes here */
%IF %SYSMACEXIST(&_opts) %THEN %DO;
%&_opts;

   
%END;

  *** =======================================================================;
  ** This will allow us to define a new temporary template;
  ods path(prepend) work.templat(update);
  ods path show;
%CompileSurvivalTemplates;


*******************************************************************************************************/;
*****  Create plot                                                                                *****/;
*******************************************************************************************************/;

ods listing close;
ods noptitle;

%IF &_orint=portrait %THEN %DO;
  ODS graphics on / border=off height=10cm width=19cm;
  GOPTIONS ymax=10cm xmax=19cm;   
  OPTIONS orientation=portrait papersize='ISO A4' nodate nonumber nobyline ; 
%END;
%ELSE %DO;
  ODS graphics on / border=off height=12cm width=25cm ;
  GOPTIONS xmax=25cm ymax=12cm;
  OPTIONS orientation=landscape papersize='ISO A4' nodate nonumber nobyline ;    
%END;

   ods graphics on / imagefmt=&_dev;
ods select SurvivalPlot;

proc lifetest data=&_inds PLOTS=SURVIVAL( ATRISK (atrisktickonly outside)= 0 TO &__maxmon BY &_timetick) alphaqt=&_alphaqt METHOD=KM CONFTYPE=LOGLOG;
   time &_time * &_cen(1);
   strata &_strata / order=internal test=none;
run;quit;

ods graphics off;
%MEND mkmplot;
**----------------------------------------------------------------**;
** Report data                       
**----------------------------------------------------------------**;
  ods path(prepend) work.templat(update);
  ods path show;
PROC TEMPLATE;
define style styles.graph;
         parent=styles.rtf;
         %** important thing to notice is the protectspecialchars, which allows us to push the RTF codes through **;
         style table from table / protectspecialchars=off;
                                                
               replace body from document /
                  bottommargin = 0.00cm
                  topmargin    = 2.50cm
                  rightmargin  = 0.00cm
                  leftmargin   = 1.10cm;

               replace fonts /
                        'CellFont'             = ("Courier New",9pt)
                        'TitleFont2'           = ("arial",9pt)
                        'TitleFont'            = ("arial",9pt)
                        'StrongFont'           = ("arial",9pt)
                        'EmphasisFont'         = ("arial",9pt)
                        'FixedEmphasisFont'    = ("arial",9pt)
                        'FixedStrongFont'      = ("arial",9pt)
                        'FixedHeadingFont'     = ("arial",9pt)
                        'BatchFixedFont'       = ("arial",9pt)
                        'FixedFont'            = ("arial",9pt)
                        'headingEmphasisFont'  = ("arial",9pt)
                        'headingFont'          = ("arial",9pt)
                        'docFont'              = ("arial",9pt);

                  style GraphFonts from GraphFonts /
                        'GraphDataFont' = ("Courier New",9pt)
                        'GraphUnicodeFont' = ("Courier New",9pt)
                        'GraphValueFont' = ("Courier New",9pt)
                        'GraphLabelFont' = ("Courier New",9pt)
                        'GraphFootnoteFont' = ("Courier New",9pt)
                        'GraphTitleFont' = ("Courier New",9pt)
                        'GraphAnnoFont' = ("Courier New",9pt); 
            style GraphData1 from GraphData1 / font=("Courier New", 9pt) contrastcolor=black;;
            style GraphData2 from GraphData2 / font=("Courier New", 9pt) contrastcolor=cx808080;
            style GraphData3 from GraphData3 / LineStyle = 3;
                  end;

            quit;
      run;  

  ODS graphics on / border=off height=12cm width=25cm ;
  GOPTIONS xmax=25cm ymax=12cm;
  OPTIONS orientation=landscape papersize='ISO A4' nodate nonumber nobyline ;   
  

ods pdf dpi=300 file="..../mygraph.pdf" style=graph;

%LET kmtype=PFS;
   
%mkmplot (_inds=adtte,
          _time=months,
          _cen =cnsr,
          _strat=trt01pn,
          _timetick=3,
          _maxtime=24,
          _ylabel="Probability of PFS",
          _legtitl=" ",
          _alphaqt=0.05,
          _fmt=5.1,
          _kmtime=,
          _opts=none,
          _opts2=none,
          _orint=landscape
          _colour=yes
          _dev=svg
                );
                
ODS pdf close;

 

1 REPLY 1
SwissC
Obsidian | Level 7

So I had a little play around with this again, if I replace

 entry &r StrVal&i &t;

with

 entry &r "&&&trt&i" &t;

with the treatment label defined outside the template then the label is printed correctly.  So it seems to be related to some kind of style applied to the StrVal within Stat.Graphics.ProductLimitSurvival

Any idea how I may get at this StrVal variable?

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 1 reply
  • 637 views
  • 0 likes
  • 1 in conversation