BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
alexgonzalez
Quartz | Level 8

Hello,

I want to include the % sign in a text in a dataset as follows:

label=%upcase('%E from FS');

 

When I pass that text in PROC SGPLOT via SGANNO, I get the following warning message:

WARNING: Apparent invocation of macro E not resolved.

 

Can you please advice on how to get rid of that message? 

I have tried different options, but nothing is working.

Thanks a lot,

A.G.

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Hi,

 

I think the key point is that SGPLOT is doing its own code generation (it has to generate PROC TEMPLATE code in the background).  And any time code is being generated, there is the potential for macro triggers to be revealed.

 

This code replicates your problem.  As you say, the DATA step does not see %E as a macro call, because it is hidden by the single quotes.  However, the PROC SGPLOT does see the % sign as a macro trigger:

 

 

data anno;
  function="text";
  x1space= 'graphpercent';
  y1space= 'graphpercent';
  y1=50;
  x1=50;
  label='%E FROM FS IN ';
run;

proc sgplot data=sashelp.class sganno=anno tmplout="c:\junk\mytmpl.sas";
 scatter x=height y=weight ;
run ;

I added the tmplout= option to the proc, so that you can see the code that SGPLOT generated.  You can see that it generates a DRAWTEXT statement for the annotation, and the value is in double quotes:

proc template;
define statgraph sgplot;
begingraph / collation=binary;
layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split);
   ScatterPlot X=Height Y=Weight / subpixel=off primary=true LegendLabel="Weight" NAME="SCATTER";
   DrawText  "%E FROM FS IN" / X=50 Y=50 XSPACE=graphpercent YSPACE=graphpercent;
endlayout;
endgraph;
end;
run;

 

While it looks funny in the DATA step code, one option would be to add %NRSTR() inside the single quotes. This will prevent SGPLOT from seeing the % sign as a macro trigger:

 

 

data anno;
  function="text";
  x1space= 'graphpercent';
  y1space= 'graphpercent';
  y1=50;
  x1=50;
  label='%nrstr(%E) FROM FS IN ';
run;

proc sgplot data=sashelp.class sganno=anno tmplout="c:\junk\mytmpl2.sas";
 scatter x=height y=weight ;
run ;

because the SGPLOT will generate:

proc template;
define statgraph sgplot;
begingraph / collation=binary;
layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split);
   ScatterPlot X=Height Y=Weight / subpixel=off primary=true LegendLabel="Weight" NAME="SCATTER";
   DrawText  "%nrstr(%E) FROM FS IN" / X=50 Y=50 XSPACE=graphpercent YSPACE=graphpercent;
endlayout;
endgraph;
end;
run;

HTH

 

 

 

 

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

View solution in original post

10 REPLIES 10
ballardw
Super User

Please show the entire code of the steps involved.

It appears that you may be using %upcase in a data step where the function should be Upcase.

alexgonzalez
Quartz | Level 8
Please, see the code below. Let me know if something is still not clear enough.
Data anno;
function="text";
x1space= 'graphpercent';
y1space= 'graphpercent';
width=200;
textweight='bold';
textsize=10;
y1=98.5;
x1=50;
label=%upcase('%E from FS.);
output;
run;

proc sgplot data=stats_plot noborder sganno=anno;
scatter y=variable x=mean / xerrorlower=p25
xerrorupper=p75
noerrorcaps;

refline 0 / axis=x
lineattrs=(thickness=3
color=blb pattern=dash);
yaxis label= %upcase('Distribution parameters') display=(noticks noline);
xaxis label= %upcase('percent') ;
run;
Thank you.
ballardw
Super User

The code shown won't run.

label=%upcase('%E from FS.);
output;

Missing a ' will cause problems.

 

Since you are dealing with literal text skip the %UPCASE function

label='%E FROM FS';

The SAS editor tyically uses ctrl+U to capitalize highlighted text.

 

The %upcase macro function means that things like % and & will get treated differently and it is a separate headache learning about correct usage. Avoid until needed.

alexgonzalez
Quartz | Level 8
In the previous code also shown below, the missing ' was accidentally deleted when I copied the code from my original code.
label=%upcase('%E from FS.);
output;
I removed the %UPCASE function as you suggested and still getting the warning message.
Additionally, let's say I also want to pass a macro variable into the label as follows:
label="%E FROM FS in &agesex";
Thanks a lot BallardW.
ballardw
Super User

@alexgonzalez wrote:
In the previous code also shown below, the missing ' was accidentally deleted when I copied the code from my original code.
label=%upcase('%E from FS.);
output;
I removed the %UPCASE function as you suggested and still getting the warning message.
Additionally, let's say I also want to pass a macro variable into the label as follows:
label="%E FROM FS in &agesex";
Thanks a lot BallardW.

The show WHERE the macro value is created. If you don't want the warning to appear then concatenating text prior that step into a single macro variable would be the answer.

This appears to do what you want without creating the warning messages.

%let agesex = something;
%let string = %nrstr(%E FROM FS IN ) &agesex.;
%put &string;

data junk;
   x=1;
   label x ="&string.";
run;
alexgonzalez
Quartz | Level 8
Sorry BallardW. I tried that, but I keep getting the error message when pass the 'junk' dataset in the SGANNO option in PROC SGPLOT.
Tom
Super User Tom
Super User

You will NOT get a message if you use single quotes around the value. The macro processor ignores macro triggers inside of quoted strings that use single quotes on the outside.  So this is fine:

label=upcase('%E from FS.');

Now your new post is probably the code that is giving you the message.  If you are doing it in a data step, like the above was used then just split the string into separate strings.

label='%E FROM FS in ' || "&agesex";

If the value of the macro variable AGESEX has % or & and you are using the statement outside of a data step then add some macro quoting. Such as:

%let agesex=40 yr old males;
%let label=%nrstr(%'%%)E FROM FS in &agesex%nrstr(%');
%put &=label;

or if you are in a data step use SYMGET() function to retrieve the macro variable's value.

label='%E FROM FS in ' || symget('agesex');

 

 

alexgonzalez
Quartz | Level 8
Hi Tom,
I tried all your options and still getting the warning message. In the following dataset, it does not 'complain' at all.
Data anno;
function="text";
x1space= 'graphpercent';
y1space= 'graphpercent';
width=200;
textweight='bold';
textsize=10;
y1=98.5;
x1=50;
label='%E FROM FS IN ' || upcase("&agesex");
output;
run;

Nevertheless, when the following PROC SGPLOT procedure is used is when I get it.

proc sgplot data=stats_plot noborder sganno=anno noautolegend;
band y=variable lower=p5 upper=p95 / transparency=0.6;
scatter y=variable x=mean / xerrorlower=p5
xerrorupper=p95
markerattrs=(symbol=circlefilled)
transparency=0;

x2axis display=(noticks nolabel) offsetmin=0.75 offsetmax=0.08;

scatter y=variable x=x1 / markerchar=mean x2axis;
scatter y=variable x=x4 / markerchar=p5 x2axis;
scatter y=variable x=x5 / markerchar=p95 x2axis;


refline 0 / axis=x
lineattrs=(thickness=3
color=blb pattern=dash);
yaxis
label= %upcase('Distribution parameters')
grid offsetmin=0.05 offsetmax=0.05
display=(noticks noline) valueattrs=(size=7);

xaxis
label= %upcase('percent differences')
grid valueattrs=(size=7)
offsetmin=0.1 offsetmax=0.3
min=-&p max=&p ;
run;
Thanks a lot,
A.G.
Quentin
Super User

Hi,

 

I think the key point is that SGPLOT is doing its own code generation (it has to generate PROC TEMPLATE code in the background).  And any time code is being generated, there is the potential for macro triggers to be revealed.

 

This code replicates your problem.  As you say, the DATA step does not see %E as a macro call, because it is hidden by the single quotes.  However, the PROC SGPLOT does see the % sign as a macro trigger:

 

 

data anno;
  function="text";
  x1space= 'graphpercent';
  y1space= 'graphpercent';
  y1=50;
  x1=50;
  label='%E FROM FS IN ';
run;

proc sgplot data=sashelp.class sganno=anno tmplout="c:\junk\mytmpl.sas";
 scatter x=height y=weight ;
run ;

I added the tmplout= option to the proc, so that you can see the code that SGPLOT generated.  You can see that it generates a DRAWTEXT statement for the annotation, and the value is in double quotes:

proc template;
define statgraph sgplot;
begingraph / collation=binary;
layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split);
   ScatterPlot X=Height Y=Weight / subpixel=off primary=true LegendLabel="Weight" NAME="SCATTER";
   DrawText  "%E FROM FS IN" / X=50 Y=50 XSPACE=graphpercent YSPACE=graphpercent;
endlayout;
endgraph;
end;
run;

 

While it looks funny in the DATA step code, one option would be to add %NRSTR() inside the single quotes. This will prevent SGPLOT from seeing the % sign as a macro trigger:

 

 

data anno;
  function="text";
  x1space= 'graphpercent';
  y1space= 'graphpercent';
  y1=50;
  x1=50;
  label='%nrstr(%E) FROM FS IN ';
run;

proc sgplot data=sashelp.class sganno=anno tmplout="c:\junk\mytmpl2.sas";
 scatter x=height y=weight ;
run ;

because the SGPLOT will generate:

proc template;
define statgraph sgplot;
begingraph / collation=binary;
layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split);
   ScatterPlot X=Height Y=Weight / subpixel=off primary=true LegendLabel="Weight" NAME="SCATTER";
   DrawText  "%nrstr(%E) FROM FS IN" / X=50 Y=50 XSPACE=graphpercent YSPACE=graphpercent;
endlayout;
endgraph;
end;
run;

HTH

 

 

 

 

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
alexgonzalez
Quartz | Level 8
Hi Quentin,
Thanks a lot for the great suggestion. That fixed the issue completely. Very much appreciated. I've dealing with that for a few days.
A.G.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 10 replies
  • 1048 views
  • 1 like
  • 4 in conversation