Hi,
I have mostly figure out arrays, but for some reason, this is not responding as I would expect. I thought that since the condition that the maximum of the array is 5 in some cases, that Any5 = 'Yes'. But, in all cases, Any5 = 'No'. This will be clear when you read the code. Why isn't Any5 = 'Yes' when at least 1 of the Ques1-Ques5 is 5? I realize that there may be more efficient ways to do this, but the point here is to learn how to use arrays. Thanks.
Data review.Any5 ; Set Learn.survey2(rename=(Ques1 = CharQ1 Ques2 = CharQ2 Ques3 = CharQ3 Ques4 = CharQ4 Ques5 = CharQ5)) ; Ques1 = input(CharQ1,5.) ; Ques2 = input(CharQ2,5.) ; Ques3 = input(CharQ3,5.) ; Ques4 = input(CharQ4,5.) ; Ques5 = input(CharQ5,5.) ; Array FindAny5{*} Ques1-Ques5 ; Do i = 1 to dim(FindAny5) ; If Max(FindAny5{i}) eq 5 then Any5 = 'Yes' ; Else Any5 = 'No' ; End ; Drop i CharQ1-CharQ5 ; Run ; Proc print data=review.Any5 noobs ; run ;
If your trying to find the max value from all the columns in a row then you don't need the DO Loop. Since you have the DO loop the array will substitute only one value (i) at a time.
You code will resolve to :
If Max(Ques1) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
If Max(Ques2) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
If Max(Ques3) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
So on ..............
If you want to perform something like :
If Max(of Ques1-Ques5) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
You need to remove the DO LOOP
data have;
input num1 num2 num3 num4 num5;
datalines;
1 2 3 4 5
;
run;
data want;
set have;
array num_5{*} num1-num5;
IF MAX(of num_5[*])=5 then val="YES";
ELSE Val="NO";
RUN;
If your trying to find the max value from all the columns in a row then you don't need the DO Loop. Since you have the DO loop the array will substitute only one value (i) at a time.
You code will resolve to :
If Max(Ques1) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
If Max(Ques2) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
If Max(Ques3) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
So on ..............
If you want to perform something like :
If Max(of Ques1-Ques5) eq 5 then Any5 = 'Yes' ;
Else Any5 = 'No' ;
You need to remove the DO LOOP
data have;
input num1 num2 num3 num4 num5;
datalines;
1 2 3 4 5
;
run;
data want;
set have;
array num_5{*} num1-num5;
IF MAX(of num_5[*])=5 then val="YES";
ELSE Val="NO";
RUN;
Since sometimes you can't use a simple function as in @SuryaKiran's solution here is an approach using LEAVE.
The LEAVE instruction terminates a loop when encountered. The code tests an exact numeric value and when (if) found sets the flag value and exits the loop the first time it is encountered. A possibly useful side affect is that the value of the loop counter will have the value of the index where the true condition was encountered. So if i=3 then you know for that record the third element of the array has the value 5.
Data review.Any5 ; Set Learn.survey2(rename=(Ques1 = CharQ1 Ques2 = CharQ2 Ques3 = CharQ3 Ques4 = CharQ4 Ques5 = CharQ5)) ; Ques1 = input(CharQ1,5.) ; Ques2 = input(CharQ2,5.) ; Ques3 = input(CharQ3,5.) ; Ques4 = input(CharQ4,5.) ; Ques5 = input(CharQ5,5.) ; Array FindAny5{*} Ques1-Ques5 ; Do i = 1 to dim(FindAny5) ; If FindAny5{i} eq 5 then do; Any5 = 'Yes' ; Leave; end; Else Any5 = 'No' ; End ; Drop i CharQ1-CharQ5 ; Run ; Proc print data=review.Any5 noobs ; run ;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.