var1 through var5 are five variables of interest. var1_suffix through var5_suffix are corresponding indicators which take values of 0 or 1. If its value=1, then I want set the corresponding variable value to missing. For example, var1=4.2 and var1_suffix=1 so I will change the value of var1 to missing, the result should be var1=. and var1_suffix=1. I wrote a macro to do this:
%DO %WHILE("a" NE "");
%IF &a._suffix=1 %THEN &a=.;
%mymacro(var1 var2 var3 var4 var5);
In fact I have lots of variables(could be var1 to varn), and so var_suffix, that's why I prefer using macro program, cause it is hard to calculate the total number of variables and the total varies everytime I run it. Also, var_suffix is named exactly start with var(i) and followed by _suffix.
Thanks. I am new to this forum and I don't know I should stay the same post until it is solved since I saw nobody respond any more. Sorry about that.
This time I used options you suggested. I tried &a._suffix and it is referencing var1_suffix to var5_suffix, that is exactly what I want (if var1_suffix=1 then I want to the value of var1 be missing). You are right, when I did this, sas loops forever and I have to quit. If I write sas code: if var1_suffix=1 then var1=. sas will not loop forever. Any suggestion to solve this problem?
In your previous posting thread and in this posting thread several folks have posted non-macro solutions using ARRAYS. I agree with all the postings that show an ARRAY solution instead of a Macro solution. In this instance, given the data you describe and your stated purpose, using ARRAYS seems the best approach.
If you rejected those solutions because you did NOT want to to rename the variables for the ARRAY statement, as shown, then you could just list the variable names on the ARRAY statement. (although being able to list numbered variables is easier -- but the number should be at the end, unless you use the : wildcard). But anyway:
input var1 var1_suffix var2 var2_suffix var3 var3_suffix var4 var4_suffix var5 var5_suffix;
4.2 1 1.8 0 2.3 0 3.5 0 2.3 1
3 0 2.5 0 5.2 1 6.4 0 2.4 0
array v var1-var5;
array vs var1_suffix var2_suffix var3_suffix var4_suffix var5_suffix ;
do i = 1 to 5;
putlog 'BEFORE IF statement ' i= v(i)= vs(i)=;
if vs(i) = 1 then v(i)=.;
putlog 'AFTER IF statement ' i= v(i)= vs(i)=;
proc print data=setmiss;
title 'Making Change Using Arrays';
var var1 var1_suffix var2 var2_suffix var3 var3_suffix var4 var4_suffix var5 var5_suffix;
Thank you very much. With no other choices I will use array statement. But I will still look if macro can do it since I think it is easier to change the string (var1 - var5 or var1_suffix - var2_suffix) in parameter in macro program rather than change it during the data step. Thanks again.
Thank you very much. The code works perfectly.
I don't quite understand the code, could you tell me why you assign K and A to local variables. I took away the piece of code: "%local K A;" and it didn't affect the result. Another thing is what "%superQ(a)" does here? I tried to use "&a" instead but didn't work.Thanks again.
It is always good to use %LOCAL for variables that are used exclusively within a macro. If you called this macro from another macro with variable K or A then your macro would use those variable and probably cause a problem. It makes it look like you know what you're doing.
%SUPERQ is "super quote" it keeps variable names like NE or AND from messing up your expression. There are other quoting functions, it is all very confusing for the first 10 or 15 years :-) The quote marks " and ' don't do quoting in macro language.
into :list1 separated by ' ',
:list2 separated by ' '
where libname eq 'WORK' and memname eq 'MYDATA'
and name like '%_suffix';
%put NOTE: LIST1=&list1;
%put NOTE: LIST2=&list2;
do _n_ = 1 to dim(s);
if s[_n_] eq 1 then v[_n_]=.;