Hi all,
We are using SAS 9.1.3 on Mainframe z/OS.
My colleague approached me asking how in an "if" statement he could check if a variable was in a range of numbers without specifying the individual members of the range. I remembered seeing a colon being used for this purpose in these forums, e.g.:
data _null_;
a=4;
if a in (1:7) then
put 'True';
else
put 'False';
run;
which my colleague then put in his code and he hasn't got back to me so I assume it is OK. This got me thinking:
Is there any direct equivalent for an alphabetic range in an "if" statement? E.g. akin to ('A':'G') but this syntax does not work
I should be back in tomorrow if you have any questions - or better still any answers!
Thanks in advance,
Amir.
hi ... no character ranges, but for a single character you could try the RANK function ... A=65, G=71
data x;
length in $3;
input x :$1. @@;
in = ifc(rank(x) in (65:71), 'YES' , 'NO');
datalines;
F G H I
;
x in
F YES
G YES
H NO
I NO
ps never knew that the default length of variables created with IFC is 200
hi ... no character ranges, but for a single character you could try the RANK function ... A=65, G=71
data x;
length in $3;
input x :$1. @@;
in = ifc(rank(x) in (65:71), 'YES' , 'NO');
datalines;
F G H I
;
x in
F YES
G YES
H NO
I NO
ps never knew that the default length of variables created with IFC is 200
Amir,
This is relatively straightforward, using a colon modifier in a slightly different way. For example:
if 'A' <=: lastname <: 'C';
This statement selects all values for LASTNAME that begin with A or B.
The colon indicates that the comparison should be made by using the number of characters in whichever string has the shorter length. Issues to be wary of: capitalization makes a difference, and the collating sequence is different on ASCII vs. EBCDIC systems. Finally, note that this is different than what you were doing before. In your numeric list, 3.5 would not be in the list. The list of 1:7 includes the integer values only. This character-based version is selecting differently, based on the range, not based on a list of values.
Good luck.
Hi,
Thank you very much for your answers; as usual I have learnt a lot more than the original question was posing.
Mike: I tried looking up an opposite for the "rank" function (returns the character for a given rank) to help this kind of code work on different platforms, because I had to change the range to (193:199) for z/OS, but I could not find any - not a problem though.
Astounding: Thank you for your solution and flagging the subtleties of the ranges for both numeric and character.
Kind regards,
Amir.
Hi ... opposite of RANK is BYTE. Try (for ASCII, Windows SAS) ...
data _null_;
do j=32 to 126;
char_var = byte(j);
put j 3. '|' char_var +(-1) '|';
end;
run;
portion of LOG ...
32| |
33|!|
34|"|
35|#|
36|$|
37|%|
38|&|
39|'|
40|(|
Hi Mike,
I already looked at the byte() and collate() functions that were referenced in the "See Also" section of the rank() definition, and neither struck me as being the clear opposite of rank() - thanks for putting me right. This forum is such an education.
Thanks again,
Amir.
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.