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

Hello, I'm new to use do loop with let macro.

 

I want to create several new variables, with if conditions on pre-existing variables.

 

Without using macro, the code will be this. A, B, C .. is old variable, _A, _B, _C ... is new variable.

 

data want;
set have;
by id;
if first.id then _A=A;
if A=1 then _A=A;
else do;
retain _A.;
end;
run;

data want;
set have;
by id;
if first.id then _B=B;
if B=1 then _B=B;
else do;
retain _B.;
end;
run;

... and so on.

 

With searching, I found it is better to use let function and do loop. However, I'm new to this. I created the code below (only A, B, C), However, it wasn't working.

 

%Let var = A B C ;
%Let _var = _A _B _C ;

data want;
set have;

do i = 1 to 3;
by id;
if first.id then scan(&_var.,i,' ')=scan(&var.,i,' ');
if scan(&var.,i,' ')=1 then scan(&_var.,i,' ')=scan(&var.,i,' ')
else do; retain scan(&_var.,i,' ');
end;
end;
run;

With log statement, there was problem in scan. It can't read 'A B C'. I hope somebody help me fixing this problem.

1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20
%Let var = A B C ;
%Let _var = _A _B _C ;

data want;
set have;
by id;
array j &var;
array k &_var;
retain k;
do over j;
 if first.id or j=1 then k=j;
end;
run;

 

Hi @km0927  What you need is not macro i'm afraid rather an ARRAY. Please observe the grouping of var and _var in two sets of arrays and the loop that traverses through the elements of the arrays. The implicit array DO OVER makes it a very convenient syntax.  

View solution in original post

4 REPLIES 4
novinosrin
Tourmaline | Level 20
%Let var = A B C ;
%Let _var = _A _B _C ;

data want;
set have;
by id;
array j &var;
array k &_var;
retain k;
do over j;
 if first.id or j=1 then k=j;
end;
run;

 

Hi @km0927  What you need is not macro i'm afraid rather an ARRAY. Please observe the grouping of var and _var in two sets of arrays and the loop that traverses through the elements of the arrays. The implicit array DO OVER makes it a very convenient syntax.  

km0927
Obsidian | Level 7

Really thanks. It worked.

 

However, how did 'k' in array worked?

 

With 'do over j', j did loop with A, B, C.

 

But there was no 'do over' with k.

 

It would be bothering, I would really appreciate your explanation.

novinosrin
Tourmaline | Level 20

Sure @km0927   the DO OVER array is an implicit array and hence there is no need to explicitly specify an index variable like do i=1 to n;

 

Though implicit there is an index variable created in the PDV by the name _I_ , however this variable is not written to the output dataset. So every time the DO OVER loop executes, _I_ is incremented by a value of 1. In essence, what happens, when _I_ is 1 , the array reference is j(_I_) or k(_I_) for the reason both J and K are nonscalar items that points to an array that are collection of variables.

 

Since J and K array are grouped with same number of items like in your instance 3 elements, it is easy to reference and loop over one array J or K as _I_ increment can correspondingly be referred for elements in K or the other array.

 

Hope that helps.

 

PS Recommended reading IMPLICIT SAS DO OVER ARRAYS online 

 

 

 

 

 

 

 

 

y

ed_sas_member
Meteorite | Level 14

Hi @km0927 

 

You should typically use an array in this case.

An array allow you to perform the same manipulation on a large range of variable.

- First, you declare the array in an ARRAY statement -> ARRAY <name of the array> (*) <$ only if character variables> <your variables>;

- Then you can loop through all the variables of the array by calling them by their name inside the array : for example, variable A is the first variable in the array "new" so you can call it old(1); variable B is equivalent to old(B); ...

data want;
	set have;
	by id;
	
	array old (*) A B C;
	array new (*) _A _B _C;
	
	do i=1 to dim(old);
		if first.id or old(i) = 1 then new(i)=old(i);
		else do;
			retain new;
		end;
	end;
	
	drop i;
run;

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 855 views
  • 2 likes
  • 3 in conversation