Data visualization with SAS programming

Multiple REFERENCELINE values, no problem. Single REFERENCELINE value does not appear

Accepted Solution Solved
Reply
Occasional Contributor DDT
Occasional Contributor
Posts: 18
Accepted Solution

Multiple REFERENCELINE values, no problem. Single REFERENCELINE value does not appear

This is a continuation of my GTL Box plot learning curve Smiley Happy 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():

  • EVAL(LENGTH(_REFLINES)) is missing, zero-length, for _REFLINES="100". Check the title text.
  • _REFLINES="100" works as expected with COLN(), if I remove the conditional code IF EVAL(LENGTH(_REFLINES) > 0) and ENDIF;.
  • Use _REFLINES="100 a" in the code, below, instead of _REFLINES="100". and I magically get the 100 line, a correct length of 5, and no syntax warning or error (but COLN() does not like "100,a").
  • Use _REFLINES="100  " (trailing blanks) in the code, below, and change LENGTH() to LENGTHC() which should not strip trailing blanks, but the single reference line is still omitted, and the length() in the title is still null.
  • _REFLINES="100 110" produces errors, just to confirm that COLN() expects comma-delimited values.

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;

 

 


Accepted Solutions
Solution
‎01-05-2016 09:27 AM
Super User
Super User
Posts: 7,711

Re: Multiple REFERENCELINE values, no problem. Single REFERENCELINE value does not appear

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;

View solution in original post


All Replies
Solution
‎01-05-2016 09:27 AM
Super User
Super User
Posts: 7,711

Re: Multiple REFERENCELINE values, no problem. Single REFERENCELINE value does not appear

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;
Occasional Contributor DDT
Occasional Contributor
Posts: 18

Re: Multiple REFERENCELINE values, no problem. Single REFERENCELINE value does not appear

Indeed, exists() does allow zero, 1 or multiple values! Although I cannot say that this works as I would expect Smiley Happy

 

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!

Occasional Contributor DDT
Occasional Contributor
Posts: 18

Re: Multiple REFERENCELINE values, no problem. Single REFERENCELINE value does not appear

And of course, not to overlook what still troubles me:

I don't understand why EVAL(LENGTH("100")) returns a null value...
Super User
Super User
Posts: 7,711

Re: Multiple REFERENCELINE values, no problem. Single REFERENCELINE value does not appear

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.

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 4 replies
  • 399 views
  • 3 likes
  • 2 in conversation