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-wordmark-2025-midnight.png

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