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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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