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

I am trying to dichotomise a few variables using a 0.5 threshold. 

 

%MACRO dichot(dichVar=);

data quasi.MVNdi;
set quasi.MVN;
%if &dichVar < 0.5 %then &dichVar = 0;
%else &dichVar = 1;; /*WHY THERE HAS TO BE 2 SEMICOLONS*/
RUN;

proc print data=quasi.mdi;
var &dichVar;
run;;

%MEND dichot;

 

%dichot(dichvar=Latest_lipid_drug);
%dichot(dichvar=Latest_diabetes);

 

somehow the results that came out were all 1 (for both variables, original values are normally distributed between -1 to 1).

 

Anywhere wrong with the code? Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

@lyfaqu wrote:

I am trying to dichotomise a few variables using a 0.5 threshold. 

 

%MACRO dichot(dichVar=);

data quasi.MVNdi;
set quasi.MVN;
%if &dichVar < 0.5 %then &dichVar = 0;
%else &dichVar = 1;; /*WHY THERE HAS TO BE 2 SEMICOLONS*/
RUN;

proc print data=quasi.mdi;
var &dichVar;
run;;

%MEND dichot;

 

%dichot(dichvar=Latest_lipid_drug);
%dichot(dichvar=Latest_diabetes);

 

somehow the results that came out were all 1 (for both variables, original values are normally distributed between -1 to 1).

 

Anywhere wrong with the code? Thanks.


Basically I do not see any need for a macro anywhere.

Any time you see a requirement to do the exact same thing to multiple variables think ARRAY instead and process all of them at once

Some thing like:

data quasi.MVNdi;
   set quasi.MVN;
   array di Latest_lipid_drug Latest_diabetes ;
   do i = 1 to dim(di);
      if not missing di[i] then di[i]= di[i] ge 0.5;
   end;
   drop i;
RUN;

Likely Problems: 1) You overwrite the output data set with each call for a single variable 2) total execution time increases with more variables. 3) You need to be careful with <  or <= comparisons about whether you want missing values included or not. Missing is < any explicit value 4) Since macro variables are compared at the compilation phase you aren't generating the code you think you are.

 

%if DOES NOT evaluate data step values but macro variable values.

 

As for why the two semicolons: run your code like this:

options mprint symbolgen;

%dichot(dichvar=Latest_lipid_drug);

to see what the macro is generating.

 

 

 

the t

View solution in original post

3 REPLIES 3
novinosrin
Tourmaline | Level 20

one is for the macro processor and the other is for compiler. It's all about timing just like in life 🙂

RTM- macro tokenisation process

Astounding
PROC Star

In other words ...

 

macro language does not read the contents of a DATA set (in nearly all cases).

 

Use DATA step statements:

 

IF instead of %IF

THEN instead of %THEN

ELSE instead of %ELSE

 

You won't need two semicolons any longer, and best of all, you will get an accurate result.

ballardw
Super User

@lyfaqu wrote:

I am trying to dichotomise a few variables using a 0.5 threshold. 

 

%MACRO dichot(dichVar=);

data quasi.MVNdi;
set quasi.MVN;
%if &dichVar < 0.5 %then &dichVar = 0;
%else &dichVar = 1;; /*WHY THERE HAS TO BE 2 SEMICOLONS*/
RUN;

proc print data=quasi.mdi;
var &dichVar;
run;;

%MEND dichot;

 

%dichot(dichvar=Latest_lipid_drug);
%dichot(dichvar=Latest_diabetes);

 

somehow the results that came out were all 1 (for both variables, original values are normally distributed between -1 to 1).

 

Anywhere wrong with the code? Thanks.


Basically I do not see any need for a macro anywhere.

Any time you see a requirement to do the exact same thing to multiple variables think ARRAY instead and process all of them at once

Some thing like:

data quasi.MVNdi;
   set quasi.MVN;
   array di Latest_lipid_drug Latest_diabetes ;
   do i = 1 to dim(di);
      if not missing di[i] then di[i]= di[i] ge 0.5;
   end;
   drop i;
RUN;

Likely Problems: 1) You overwrite the output data set with each call for a single variable 2) total execution time increases with more variables. 3) You need to be careful with <  or <= comparisons about whether you want missing values included or not. Missing is < any explicit value 4) Since macro variables are compared at the compilation phase you aren't generating the code you think you are.

 

%if DOES NOT evaluate data step values but macro variable values.

 

As for why the two semicolons: run your code like this:

options mprint symbolgen;

%dichot(dichvar=Latest_lipid_drug);

to see what the macro is generating.

 

 

 

the t

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

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
  • 823 views
  • 5 likes
  • 4 in conversation