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;
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.
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;
...
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 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.