BookmarkSubscribeRSS Feed
Julie4
Fluorite | Level 6

Hello,

I'm writing it to ask for help coding with macro code below.

It's my first time seeing macro code and I have to change it to ordinary(non macro) code.

Can anybody help me changing this macro code to ordinary sql and data code?

 

Thank you.

 


%macro CI1(indata=,xvar=,wealth=,outdata=);


/* First step*/
data _null_;
set &indata nobs=nobs end=end;
if end;
call symputx("number",nobs);
run;

/* Second : ranking wealth*/
proc rank data =&indata out = &xvar.ranka; 
var &wealth; 
ranks wealthrank; 
run;

proc means data = &xvar.ranka noprint; 
var wealthrank;

 

/* wealthrank_max*/
output out = wealthrank_max max = wealthrank_max;
run;

 

/* wealthrank _ max,wealthrank_max*/
data &xvar.rank; 
set &xvar.ranka ;
if _n_ = 1 then set wealthrank_max; 
wealthrank_frac = wealthrank/wealthrank_max; 
run;

 

/* Third : covariance*/
proc corr data = &xvar.rank COV outp=cov(type=cov) noprint;
var &xvar wealthrank_frac; 
run;
data cova; set cov;
if _name_ ="wealthrank_frac" and _type_="COV"; cov = &xvar; 
keep cov; 
run;

 

/* Fourth. Calculating CI*/
proc means data = &indata noprint;
var &xvar; output out = mu mean = mu; 
run;
data mua; set mu; keep mu; 
run;
data ci; merge cova mua; 
CI = 2* COV/mu;
run;

 

 

data &outdata;
length xvar $ 15;
xvar="&xvar";
n=&number;
set ci(keep=ci);
run;

 

proc datasets lib=work noprint;
delete &xvar.: ci cov cova mu mua wealthrank_max ;
run;
quit;
%mend;

 

3 REPLIES 3
PaigeMiller
Diamond | Level 26

It's my first time seeing macro code and I have to change it to ordinary(non macro) code.

Can anybody help me changing this macro code to ordinary sql and data code?

 

Why change it if it is working? Changing it to non-macro code removes some of the flexibility and power that is in the macro. And you can't change it to "ordinary sql and data code", you might be able to change it to DATA step plus PROC RANK, PROC CORR, PROC MEANS and PROC DATASETS code. There is no SQL equivalent for most of this.

--
Paige Miller
Tom
Super User Tom
Super User

Converting that macro will be simple as it has no macro logic at all.

Step 1. Replace the %MACRO statement with a series of %LET statement that will assign values to the macro variables.

Step 2. Remove the %MEND statement.

 

Q.E.D.

 

While you are at it you could fix the first step to properly handle empty datasets and take less time with non-empty dataset.

%let indata= ;
%let xvar=;
%let wealth= ;
%let outdata=;

/* First step*/
data _null_;
  call symputx("number",nobs);
  stop;
  set &indata nobs=nobs;
run;

...

 

 

Kurt_Bremser
Super User

This:

proc means data = &xvar.ranka noprint; 
var wealthrank;
 
/* wealthrank_max*/
output out = wealthrank_max max = wealthrank_max;
run;
 
/* wealthrank _ max,wealthrank_max*/
data &xvar.rank; 
set &xvar.ranka ;
if _n_ = 1 then set wealthrank_max; 
wealthrank_frac = wealthrank/wealthrank_max; 
run;

can be done in a single SQL:

proc sql;
create table &xvar.rank as
  select
    *,
    wealthrank / max(wealthrank) as wealthrank_frac
  from &xvar.ranka
;
quit;

 

PS: you must test this with your real data to see which of the two methods performs better. If the two-step PROC MEANS / DATA is significantly better, keep it.

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 3 replies
  • 562 views
  • 2 likes
  • 4 in conversation