Hi,
I am having an array of variables day1-day10 (10 variables) including character values there, such as a1, b32, c56, d9876, e298, and f402. I want to create a new variable---important_day. Only when day1 (or day2, day3, or...day10)=f402 then important_day=Yes, when day1 (or day2, day3, or...day10) is anyone else then important_day=No.
Please advice how to use character variables in if then statement in an array in SAS.
Thank you in advance!
with regards,
Like this?
data have;
input (day1-day10)(:$);
datalines;
a1 b32 c56 d9876 e298 f402 a1 b32 c56 d9876 e298
a1 b32 c56 d9876 e298 a1 a1 b32 c56 d9876 e298
;
data want;
set have;
array d{10} day1-day10;
important_day=ifc(whichc('f402', of d[*]) > 0, 'Yes', 'No');
run;
What do you mean by 'it didn't work'? Did you get an error in the log or did the results just differ from what you want? And if so, how? 🙂
The IFC Function Simply returns 'Yes' if the first argument is true ('f402' is there) and 'No' if the first argument is false ('f402' is not there).
Just to be clear, the above is equivalent to
data want;
set have;
array d{10} day1-day10;
if whichc('f402', of d[*]) > 0 then important_day='Yes';
else important_day='No';
run;
There's no need for WHICHC, as the search can be done directly against the direct array name reference:
data have ; input (day1-day10) ($) ; cards ; a1 b32 c56 d9876 e298 f402 a1 b32 c56 d9876 e298 a1 b32 c56 d9876 e298 a1 a1 b32 c56 d9876 e298 ; run ; data want ; set have ; array d day: ; important_day = put (ifc ("f402" in d, "yes", "no"), $3.) ; run ;
Kind regards
Paul D.
You can try also this
data want;
set have;
length important_day $3;
important_day="No";
array day(10) $;
do i=1 to dim(day);
if day(i)= "f402" then do;
important_day="Yes"; /* When "f402" is found, change the flag variable to "Yes" */
leave; /* No need to continue checking because "f402" is found */
end;
end;
run;
@hashman of course. Good catch!
Not sure how using one method (IN operator) is better/worse than the other (WHICHC() function).
Note that if you use the function there is no need to define an array.
@Tom:
I don't think it's a matter of "better" or "worse"; just two different pieces of SAS functionality.
If you only want to know if the value to which an expression resolves is present an array A, then coding:
<expression> IN A
is less busy code-wise (and, IMO, more self-explanatory) than:
whichn (<expression>, of A[*]) > 0
Besides, IN is good for both numeric and character arrays, while WHICHN/C has to be type-specific. If you want to know the index of the first array item where <expression> is found, then of course IN doesn't tell while WHICHN/C does.
Performance-wise:
For example, run the following two pieces of code and compare their RAM footprints:
option fullstimer ;
data _null_ ;
array a [1000000] _temporary_ (1:1000000) ;
do x = 1, 500000, 1000000 ;
f1 = x in a ;
f2 = x + 1 in a ;
f3 = x - 1 in a ;
put (f1-f3) (=) ;
end ;
run ;
data _null_ ;
array a [1000000] _temporary_ (1:1000000) ;
do x = 1, 500000, 1000000 ;
f1 = whichn (x, of a[*]) > 0 ;
f2 = whichn (x + 1, of a[*]) > 0 ;
f3 = whichn (x - 1, of a[*]) > 0 ;
put (f1-f3) (=) ;
end ;
run ;
Then comment out one or two calls for IN and WHICHN and watch what FULLSTIMER reports compared to the uncommented version.
Kind regards
Paul D.
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.