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

Hello,

new day new question. This time I want to calculate bandwidth of a histogram inside a makro which also creates the histogram. Here is some data I'm using:

data plot;
 do i =1 to 1000;
 y = rannor(1234) ;
 y1 = rannor(1235) ;

 output;
 end;
 run;
 
data varCorr;
input correlation ;
   datalines;
    4
    ;

The data is the used in the macro:

%MACRO createPlot(dataPlot, varCorr, obs ); 
  data bandwidth;
  set &varCorr;
  b = 3.5 * y/(&obs**(1/3));
  %let b = %SYSEVALF(b);
proc sgplot data=&dataPlot;
  histogram y / binwidth=b transparency=0.5;
  histogram y1 / binwidth=b transparency=0.5;           
  density y / type=kernel lineattrs=GraphData1;  
  density y1 / type=kernel lineattrs=GraphData2;  
  xaxis label="bla" ;
  keylegend "yK" "yG" / across=1 position=TopRight location=Inside;
run;
%MEND;

I want to calculate the b first and use it later in the proc sgplot when plotting the histogram.

I think the problem is in this line:

  %let b = %SYSEVALF(b);

But I cannot figure it out how to fix it by myself.

Thanks for your help.

1 ACCEPTED SOLUTION

Accepted Solutions
Ron_MacroMaven
Lapis Lazuli | Level 10

fail.1. your macro variable assignment statement 'happens' before the data step is processed.

fail.2. b is a (local) data set variable, which cannot be used in a global statement.

 

use call symput which does what you want: create a macro variable with the value of the data step variable b;

this assignment happens after the data step completes, thus the run statement in this code.

 

%local b;
call symputx('b',b);
run;
%put echo &=b;

hth

Ron Fehd  global, or local, maven

View solution in original post

2 REPLIES 2
Ron_MacroMaven
Lapis Lazuli | Level 10

fail.1. your macro variable assignment statement 'happens' before the data step is processed.

fail.2. b is a (local) data set variable, which cannot be used in a global statement.

 

use call symput which does what you want: create a macro variable with the value of the data step variable b;

this assignment happens after the data step completes, thus the run statement in this code.

 

%local b;
call symputx('b',b);
run;
%put echo &=b;

hth

Ron Fehd  global, or local, maven

Tom
Super User Tom
Super User

This part of your code does not make any sense.

data bandwidth;
  set &varCorr;
  b = 3.5 * y/(&obs**(1/3));
  %let b = %SYSEVALF(b);
run;

The %LET macro assignment statement will happen while the macro processor is processsing the code so it is the same as if you wrote it this way.

%let b = %SYSEVALF(b);
data bandwidth;
  set &varCorr;
  b = 3.5 * y/(&obs**(1/3));
run;

Which of course still makes no sense as the letter B will not be evaluated to anything by the %SYSEVALF() macro function.

Also no where in your code to make any reference to this macro variable B that you were trying to calculate.

 

 

You need to know what code you want to generate before you start using macro logic to generate code.

Looks like you want to combine your two datasets, calculate something and then plot it.  But you haven't given us enough information to know how to do that.

 

For example your code references a variable named Y1 that is not defined anywhere.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 1284 views
  • 1 like
  • 3 in conversation