BookmarkSubscribeRSS Feed
lueryy2000
Calcite | Level 5
Hi,

I have a dataset containing two groups of experiment data and I want to decide if the result is positive based on different criteria. Below is my data:

data mydata;
input var1 var2 var3 var4 MFI_var5 MFI_var6 MFI_var7;
datalines;
4.2 1.8 0.3 . 30 15 10
0.7 0.8 3.3 . 80 20 .
;
run;

var1 - var4 came from experiment1, MFI_var5 - MFI_var7 came from experiment2 (they have prefix of MFI). The object is if the value of experiment1 > 1.5 then it is positive, while for experiment2 it needs to be greater than 15 to be positive. And I will create indicators, whose values are 0 or 1, showing if it is positive or not. Below is my code:

%MACRO mymacro(varLIST);
%local k a b;
DATA mydataout;
SET mydata;
%LET K=1;
%LET a=%SCAN(&varLIST,&K);
%LET b=%INDEX(&a,'MFI_');
%DO %WHILE (&a NE %STR() AND &b=0);
IF &a GE 1.5 THEN expt1_&a._pos = 1;
%LET K=%EVAL(&K+1);
%LET a=%SCAN(&varLIST,&K);
%LET b=%INDEX(&a,'MFI_');
%END;

%DO %WHILE (&a NE %STR() AND &b=1);
IF &a GT 15 THEN expt2_&a._pos = 1;
%LET K=%EVAL(&K+1);
%LET a=%SCAN(&varLIST,&K);
%LET b=%INDEX(&a,'MFI_');
%END;
RUN;
%MEND;
%mymacro(var1 var2 var3 var4 MFI_var5 MFI_var6 MFI_var7);

The positive indicators are expt1_varname_pos for experiment1, and expt2_varname_pos for experiment2, here varname are: var1 - var4 and MFI_var5 - MFI_var7, I would prefer not change the varname, just dump them in the middle. Since variables from experiment2 have prefix MFI, so I used %index function to look for if 'MFI' appear in variable, it came from experiment2 and the cut off point for positive would be 15, otherwise it is 1.5. So I want to my final report would be following:

var1 var2 var3 var4 MFI_var5 MFI_var6 MFI_var7 expt1_var1_pos expt1_var2_pos expt1_var3_pos expt1_var4_pos expt1_MFI_var5_pos expt1_MFI_var6_pos expt1_MFI_var7_pos
4.2 1.8 0.3 30 15 10 1 1 1
0.7 0.8 3.3 80 20 1 1 1

However, when I ran my macro, &b always be 0 and sas still use cut off of 1.5 instead of 15 for experiment2. It gave the following incorrect result:
var1 var2 var3 var4 MFI_var5 MFI_var6 MFI_var7 expt1_var1_pos expt1_var2_pos expt1_var3_pos expt1_var4_pos expt1_MFI_var5_pos expt1_MFI_var6_pos expt1_MFI_var7_pos
4.2 1.8 0.3 30 15 10 1 1 1 1 1
0.7 0.8 3.3 80 20 1 1 1

I have tons of such data so I prefer use macro to do this. Does anybody know why %index doesn't function here?

Thanks in advance,
Lu
4 REPLIES 4
Peter_C
Rhodochrosite | Level 12
Quote confusion!
In macro processing quote marks are treated as part of the data.
Use %str() function to protect a string from being interpreted as potentially syntax

good luck
peterC
lueryy2000
Calcite | Level 5
Sorry I am not so familiar with quote function. Could you tell me where should I quote?

Thanks,
Lu
Peter_C
Rhodochrosite | Level 12
%LET b=%INDEX(&a,'MFI_');

that is not likely to do what you want, because it is "the wrong kind of quoting". It is data step quoting which solves compiling syntax problems in a data step, but does not do what you were hoping in your macro
MFI_ needs no quoting in a macro because the macro compiler has no difficulty identifying what it is - just an inactive string.
Equally 'MFI_' is used by the macro compiler as a string, but I do not imagine you will ever see &a holding a value like 'MFI_'12345dfgh. Your macro fails because your %index() is looking for single quotes within the value of &a
Macro quoting protects macro values to ensure their contents are treated as syntax only when needed and not too early as in
%if &state eq WA %then %...............
what do you imagine is understood by this when &state holds OR or NE
Then macro quoting helps
%if %str(&state) eq WA %then %...............
might do what was really wanted.

Here your macro might work if those %index() calls contain no single quotes.

good luck
peterC
lueryy2000
Calcite | Level 5
Now I see the problem. It works well. I appreciated your explanation.

Lu

SAS Innovate 2025: Register Today!

 

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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