BookmarkSubscribeRSS Feed
lueryy2000
Calcite | Level 5
Hi,

I posted it yesterday and got some valuable feedback, but it wasn’t what I want. Sorry to bother again. Below is my mini-version data:

data mydata;
input var1 var1_suffix var2 var2_suffix var3 var3_suffix var4 var4_suffix var5 var5_suffix;
datalines;
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
3.1 0 6.7 0 5.1 1 3 0 4 0
;
run;

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:

%MACRO mymacro(varLIST);
DATA mydataout;
SET mydata;
%LET K=1;
%LET a=%SCAN(&varLIST,&K);
%DO %WHILE("a" NE "");
%IF &a._suffix=1 %THEN &a=.;
%LET K=%EVAL(&K+1);
%LET a=%SCAN(&varLIST,&K);
%END;
RUN;
%MEND;
%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,
Lu
13 REPLIES 13
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
You still are referencing the character "a" in your %DO statement. Also, now you are testing a SAS macro variable named var1_suffix which I don't believe is your intention.

Therefore the macro you have coded just loops continuously and will not compile.

I encourage the OP to using this OPTIONS statement to generate some self-help diagnostics:

OPTIONS SOURCE SOURCE2 MGEN SGEN MPRINT /* MLOGIC */ ;

Lastly, I don't understand why you abandoned your other post - that is where the discussion should stay until resolved.

Scott Barry
SBBWorks, Inc. Message was edited by: sbb
lueryy2000
Calcite | Level 5
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?

Thanks,
Lu
SASPhile
Quartz | Level 8
I changed the variable name var1_suffix etc etc to suffix_1 for the convenience of array declaration.

data mydata;
input var1 suffix_1 var2 suffix_2 var3 suffix_3 var4 suffix_4 var5 suffix_5;
datalines;
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
3.1 0 6.7 0 5.1 1 3 0 4 0
;
run;


data mydata_v1;
set mydata;
array vari(*) var:;
array suffi(*) suffix:;
do i= 1 to dim(vari);
if suffi(i)=1 then vari(i)=.;
end;
run;
lueryy2000
Calcite | Level 5
Thank you. Although it is not macro what I am looking for, I appreciated a lot.
SASPhile
Quartz | Level 8
By using colon(:) in the array declaration you have the degree of freedom from not naming the variable list.if the variable list exceeds a certain number that will be pain the fingers to type them all.

Caveat:you should have the variable list sharing the same name with a number at the end.
lueryy2000
Calcite | Level 5
Thank you. Although it is not macro what I am looking for, I appreciated a lot.
Cynthia_sas
SAS Super FREQ
Hi:
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:
[pre]
data mydata;
input var1 var1_suffix var2 var2_suffix var3 var3_suffix var4 var4_suffix var5 var5_suffix;
datalines;
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
;
run;

data setmiss;
set mydata;
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)=;
end;
run;

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;
run;
[/pre]

Here's a good introduction to ARRAY processing:
http://www2.sas.com/proceedings/forum2007/273-2007.pdf

cynthia
lueryy2000
Calcite | Level 5
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.

Lu
data_null__
Jade | Level 19
Your macro was close. Here is a working version.

[pre]
%MACRO mymacro(varLIST);
%local K A;
DATA mydataout;
SET mydata;
%LET K=1;
%LET a=%SCAN(&varLIST,&K);
%DO %WHILE(%superQ(a) NE);
if &a._suffix=1 THEN &a=.;
%LET K=%EVAL(&K+1);
%LET a=%SCAN(&varLIST,&K);
%END;
RUN;
%MEND mymacro;
options mprint=1;
%mymacro(var1 var2 var3 var4 var5);
options mprint=0;
[/pre]
lueryy2000
Calcite | Level 5
Hi,
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.
data_null__
Jade | Level 19
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.

This guys knows everything about the subject.
http://www.lexjansen.com/sesug/2010/BB10.Whitlock.pdf
lueryy2000
Calcite | Level 5
Thanks so much. I really appreciate it.
data_null__
Jade | Level 19
Turn the problem around and use the SUFFIX varaibles to drive the code. Then you don't need to "touch" the VARS at all. Let the list of suffix vars make both lists.

[pre]
data mydata;
input var1 var1_suffix var2 var2_suffix var3 var3_suffix var4 var4_suffix var5 var5_suffix;
datalines;
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
3.1 0 6.7 0 5.1 1 3 0 4 0
;
run;

proc sql;
select
name,
substr(name,1,find(name,'_suffix',-length(name))-1)
into :list1 separated by ' ',
:list2 separated by ' '
from dictionary.columns
where libname eq 'WORK' and memname eq 'MYDATA'
and name like '%_suffix';
quit;
run;
%put NOTE: LIST1=&list1;
%put NOTE: LIST2=&list2;

data recode;
set mydata;
array s
  • &list1;
    array v
  • &list2;

    do _n_ = 1 to dim(s);
    if s[_n_] eq 1 then v[_n_]=.;
    end;
    run;

    proc print;
    run;
    [/pre]
  • 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
    • 13 replies
    • 1074 views
    • 0 likes
    • 5 in conversation