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

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;
1 ACCEPTED SOLUTION

Accepted Solutions
yabwon
Onyx | Level 15

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

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



View solution in original post

6 REPLIES 6
ChrisNZ
Tourmaline | Level 20

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'));

 

 

Ronein
Meteorite | Level 14
May you please show using array?
ChrisNZ
Tourmaline | Level 20

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

yabwon
Onyx | Level 15

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

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Ronein
Meteorite | Level 14
Great and thank you.
A question related to first code.
You wrote
If 101 in x or 102 in x or 103 in x
Could you wrote
If x in (101,102,103)??
yabwon
Onyx | Level 15

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?

  • "If at least one element of left array in right array then True" or
  • "If all elements of left array in right array then True"?

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.
_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 6 replies
  • 928 views
  • 7 likes
  • 3 in conversation