This is a continuation of my GTL Box plot learning curve 🙂 I have Win64 SAS 9.4 M2.
Working with the code, below, I can easily get either zero or multiple reference line(s) to display. For example, use _REFLINES="0,9" in the code, below, instead of _REFLINES="100". But I cannot get exactly 1 reference line, e.g., 100, to conditionally appear.
I am trying to:
Specifying exactly 1 reference line does not work, and seems to fail because the EVAL(LENGTH(_REFLINES)) return value is missing when _REFLINES contains only digits. Note that I have printed the result of this evaluation in the graph title.
Without a proper result from eval(length()), it's hard to program around using COLN() or a single value.
I've tried searching these communities, as well as SAS Notes.
Notable behavior, the same whether I use LENGTH() or LENGTHC():
Are there some known problems with EVAL(LENGTH(...)) or fixes in SAS 9.4 after M2?
Must the string to test include some non-digit, non-space character (a bit unexpected to me)?
Here's the play code, and thanks for any advice or alternate approach:
proc template; define statgraph xalignedstats; dynamic _GRP _CAT _MEASURE _REFLINES; begingraph / border=false dataskin=none; entrytitle 'Check result of eval(length(_REFLINES)) [' EVAL(LENGTH(_REFLINES)) ']'; layout overlay / walldisplay=none xaxisopts=(discreteopts=(tickvaluefitpolicy=split)); boxplot x=_CAT y=_MEASURE / group=_GRP groupdisplay=cluster; IF (length(_REFLINES) > 0) referenceline y=eval(coln(_REFLINES)) / lineattrs=(color=red); ENDIF;
endlayout; endgraph; end; run; proc sgrender data=sashelp.heart template=xalignedstats; dynamic _GRP ='bp_status' _CAT ='smoking_status' _MEASURE ='diastolic' _REFLINES="100" ; run;
Can you not use the exists() function on the _REFLINES variable? The below works fine on mine:
proc template; define statgraph xalignedstats; dynamic _GRP _CAT _MEASURE _REFLINES; begingraph / border=false dataskin=none; entrytitle 'Check result of eval(length(_REFLINES)) [' EVAL(LENGTH(_REFLINES)) ']'; layout overlay / walldisplay=none xaxisopts=(discreteopts=(tickvaluefitpolicy=split)); boxplot x=_CAT y=_MEASURE / group=_GRP groupdisplay=cluster; IF (exists(_REFLINES) > 0) referenceline y=eval(coln(_REFLINES)) / lineattrs=(color=red); ENDIF; endlayout; endgraph; end; run; proc sgrender data=sashelp.heart template=xalignedstats; dynamic _GRP ='bp_status' _CAT ='smoking_status' _MEASURE ='diastolic' _REFLINES="100"; run;
Can you not use the exists() function on the _REFLINES variable? The below works fine on mine:
proc template; define statgraph xalignedstats; dynamic _GRP _CAT _MEASURE _REFLINES; begingraph / border=false dataskin=none; entrytitle 'Check result of eval(length(_REFLINES)) [' EVAL(LENGTH(_REFLINES)) ']'; layout overlay / walldisplay=none xaxisopts=(discreteopts=(tickvaluefitpolicy=split)); boxplot x=_CAT y=_MEASURE / group=_GRP groupdisplay=cluster; IF (exists(_REFLINES) > 0) referenceline y=eval(coln(_REFLINES)) / lineattrs=(color=red); ENDIF; endlayout; endgraph; end; run; proc sgrender data=sashelp.heart template=xalignedstats; dynamic _GRP ='bp_status' _CAT ='smoking_status' _MEASURE ='diastolic' _REFLINES="100"; run;
Indeed, exists() does allow zero, 1 or multiple values! Although I cannot say that this works as I would expect 🙂
I did not expect EXISTS() to return zero when _REFLINES has a value that resolves to null -- e.g., pass in "&ref_lines" that resolves to "". According to EXISTS() documentation: "If item is a dynamic / macro variable, then it tests whether there has been a run-time initialization of the variable."
I expected that setting _REFLINES="&ref_lines" nonetheless counts as run-time initialization, even if &ref_lines resolves to a null string. I expected EXISTS("") to return 1, but LENGTH("") to return 0. So I didn't consider using EXISTS(). Lesson learned. And thanks for a solution!
Yes, to be honest I am not sure why that doesn't work. It looks valid, but I rarely use conditionals in templates as there isnt a debugger for them, it would be a good feature if you could put this type of thing to the log to see what the condition being evaluated is, could it be that the eval in this instance is called with the text 'length("100,110")' so its not call the function just evaluating certain characters. I don't know I am afraid, good question to put to tech support.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.