Hello
What is the way to write this code in more efficeient way (less code )?
Data have;
input id X1 X2 X3 X4 X5 X6 X7 ;
cards;
1 0 0 0 0 0 0 0
2 101 0 0 0 0 0 0
3 0 0 101 102 0 0 103
4 0 0 0 0 0 0 105
5 0 0 0 0 0 0 0
6 105 0 0 0 0 0 0 ;
Run;
/**ID1- white because all zeros
ID2-Red because have at least one 101/102/103
ID3-Red because have at least one 101/102/103
ID4-Yellow because doesnt have 101/102/103 AND have at least one element that is not zero
ID5- white because all zeros
ID6-Yellow because doesnt have 101/102/103 AND have at least one element that is not zero
***/
Data wanted;
set have;
IF X1 in (101,102,103)
OR
X2 in (101,102,103)
OR
X3 in (101,102,103)
OR
X4 in (101,102,103)
OR
X5 in (101,102,103)
OR
X6 in (101,102,103)
OR
X7 in (101,102,103)
then Ind='Red';
else IF X1 not in (101,102,103)
and
X2 not in (101,102,103)
and
X3 not in (101,102,103)
and
X4 not in (101,102,103)
and
X5 not in (101,102,103)
and
X6 not in (101,102,103)
and
X7 not in (101,102,103)
and
(LENGTH (put(X1,best.)>=2 OR LENGTH (put(X2,best.))>=2 OR LENGTH (put(X3,best.))>=2
OR LENGTH (put(X4,best.))>=2 OR LENGTH (put(X5,best.))>=2 OR LENGTH (put(X6,best.))>=2
OR LENGTH (put(X7,best.))>=2)
then Ind='Yellow';
else IF X1=0 AND X2=0 AND X3=0 AND X4=0 AND X5=0 AND X6=0 AND X7=0 then Ind='White';
Run;
One more, not as compact as the one @ChrisNZ offered but works on numeric values only,
data wanted;
set have;
length Ind $ 10;
array X[*] x1--x7;
if 101 in X or 102 in X or 103 in X then Ind='Red';
else if 101 not in X and 102 not in X and 103 not in X
and max(of X[*]) > 0 then Ind='Yellow';
else if sum(of X[*]) = 0 then Ind='White';
run;
proc print data = wanted;
run;
but even shorter when combined with @ChrisNZ 's second one:
data wanted;
set have;
length Ind $ 10;
array X[*] x1--x7;
if 101 in X or 102 in X or 103 in X then Ind='Red';
else if sum(of X[*]) = 0 then Ind='White';
else Ind='Yellow';
run;
Bart
This?
if index(catx(' ',of X1-X6),'101') | index(catx(' ',of X1-X6),'102') | index(catx(' ',of X1-X6),'103') then IND='red';
else if sum(of X1-X6)=0 then IND='White'
else IND='Yellow';
Even less code
if prxmatch('/101|102|103/',catx(' ',of X1-X6)) then IND='red';
else if sum(of X1-X6)=0 then IND='White'
else IND='Yellow';
Even less
IND=ifc( prxmatch('/10[123]/',catx(' ',of X1-X6)) ,'Red'
,ifc( ^sum(of X1-X6) , 'White', 'Yellow'));
1. You've been shown how to use arrays countless times
2. There's no need for arrays here as the variable names can be referenced with the hyphen shortcut: VAR1-VAR6
One more, not as compact as the one @ChrisNZ offered but works on numeric values only,
data wanted;
set have;
length Ind $ 10;
array X[*] x1--x7;
if 101 in X or 102 in X or 103 in X then Ind='Red';
else if 101 not in X and 102 not in X and 103 not in X
and max(of X[*]) > 0 then Ind='Yellow';
else if sum(of X[*]) = 0 then Ind='White';
run;
proc print data = wanted;
run;
but even shorter when combined with @ChrisNZ 's second one:
data wanted;
set have;
length Ind $ 10;
array X[*] x1--x7;
if 101 in X or 102 in X or 103 in X then Ind='Red';
else if sum(of X[*]) = 0 then Ind='White';
else Ind='Yellow';
run;
Bart
1) No, syntax issue (see the log below). But you could test it yourself 🙂 See @Kurt_Bremser's maxim no.4
2) How would you interpret such code? X is an array, (101,102,103) is also "kind of an array".
What should such syntax: "array in array" mean?
You can always test each element of X against (101,102,103) in a do-loop. But since X is "bigger" I would do a loop over "10_"s.
Frankly speaking the "in" operator is probably a loop under the hood too, with a "break" when success probably too.
Bart
1 data wanted; 2 set have; 3 4 length Ind $ 10; 5 array X[*] x1--x7; 6 7 if X in (101,102,103) then Ind='Red'; ERROR: Illegal reference to the array X. 8 else if sum(of X[*]) = 0 then Ind='White'; 9 else Ind='Yellow'; 10 11 run; NOTE: The SAS System stopped processing this step because of errors.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.