Hi all,
For my question I'm using a dataset similar to the one below:
data sample;
input var1 $ var2 $ var3 $ var4 $ x1 $ x2 $ x3 $ x4 $;
datalines;
a b c d 9 8 7 6
b c d e 8 7 6 5
c d e f 7 6 5 4
d e f g 6 5 4 3
e f g h 5 4 3 2
f g h i 4 3 2 1
g h i j 3 2 1 0
;
run;
I'm trying to detect whether var1-var4 has an "e" or "f" in it and whether x1-x4 has a "7" or "2" in it. My code to complete this is similar to what follows:
data record;
set sample;
array var {4} $ var1-var4;
array x {4} $ x1-x4;
array cond (2) cond1-cond2 (2*0);
do i=1 to 4;
if var[i] in ("e", "f") then cond1=1;
if x[i] in ("7", "2") then cond2=1;
end;
drop i;
run;
My problem is that once cond# is given a value of 1, it does not reset to 0 and will continue to be 1 for all following observations regardless of whether the condition is met or not.
How might I be able to implement a code that will let me given cond# a value of 1 or 0 based on checking each variable in their respective arrays? Am I incorrectly using the if/then function?
Thanks for any help or ideas you have.
use boolean and not initialize array 2*0 which retains across
data sample;
input var1 $ var2 $ var3 $ var4 $ x1 $ x2 $ x3 $ x4 $;
datalines;
a b c d 9 8 7 6
b c d e 8 7 6 5
c d e f 7 6 5 4
d e f g 6 5 4 3
e f g h 5 4 3 2
f g h i 4 3 2 1
g h i j 3 2 1 0
;
run;
data record;
set sample;
array var {4} $ var1-var4;
array x {4} $ x1-x4;
/* array cond (2) cond1-cond2 ;not needed*/
do i=1 to 4;
if not cond1 then cond1=var[i] in ("e", "f");
if not cond2 then cond2=x[i] in ("7", "2");
end;
drop i;
run;
use boolean and not initialize array 2*0 which retains across
data sample;
input var1 $ var2 $ var3 $ var4 $ x1 $ x2 $ x3 $ x4 $;
datalines;
a b c d 9 8 7 6
b c d e 8 7 6 5
c d e f 7 6 5 4
d e f g 6 5 4 3
e f g h 5 4 3 2
f g h i 4 3 2 1
g h i j 3 2 1 0
;
run;
data record;
set sample;
array var {4} $ var1-var4;
array x {4} $ x1-x4;
/* array cond (2) cond1-cond2 ;not needed*/
do i=1 to 4;
if not cond1 then cond1=var[i] in ("e", "f");
if not cond2 then cond2=x[i] in ("7", "2");
end;
drop i;
run;
WHICHC() + OR
data want; set sample; cond1 = whichc('e', of var1-var4) | whichc('f', of var1-var4); cond2 = whichc('7', of x1-x4) | whichc('2', of x1-x4); run;
This works for me.
@jdchang wrote:
Hi all,
For my question I'm using a dataset similar to the one below:
data sample; input var1 $ var2 $ var3 $ var4 $ x1 $ x2 $ x3 $ x4 $; datalines; a b c d 9 8 7 6 b c d e 8 7 6 5 c d e f 7 6 5 4 d e f g 6 5 4 3 e f g h 5 4 3 2 f g h i 4 3 2 1 g h i j 3 2 1 0 ; run;
I'm trying to detect whether var1-var4 has an "e" or "f" in it and whether x1-x4 has a "7" or "2" in it. My code to complete this is similar to what follows:
data record; set sample; array var {4} $ var1-var4; array x {4} $ x1-x4; array cond (2) cond1-cond2 (2*0); do i=1 to 4; if var[i] in ("e", "f") then cond1=1; if x[i] in ("7", "2") then cond2=1; end; drop i; run;
My problem is that once cond# is given a value of 1, it does not reset to 0 and will continue to be 1 for all following observations regardless of whether the condition is met or not.
How might I be able to implement a code that will let me given cond# a value of 1 or 0 based on checking each variable in their respective arrays? Am I incorrectly using the if/then function?
Thanks for any help or ideas you have.
When you initialize an array, it also does an implicit retain on those variables. You can get around that by not initializing them in the ARRAY statement but after the fact, or not at all unless it's needed.
@jdchang wrote:
Hi all,
For my question I'm using a dataset similar to the one below:
data sample; input var1 $ var2 $ var3 $ var4 $ x1 $ x2 $ x3 $ x4 $; datalines; a b c d 9 8 7 6 b c d e 8 7 6 5 c d e f 7 6 5 4 d e f g 6 5 4 3 e f g h 5 4 3 2 f g h i 4 3 2 1 g h i j 3 2 1 0 ; run;
I'm trying to detect whether var1-var4 has an "e" or "f" in it and whether x1-x4 has a "7" or "2" in it. My code to complete this is similar to what follows:
data record; set sample; array var {4} $ var1-var4; array x {4} $ x1-x4; array cond (2) cond1-cond2 (2*0); do i=1 to 4; if var[i] in ("e", "f") then cond1=1; if x[i] in ("7", "2") then cond2=1; end; drop i; run;
My problem is that once cond# is given a value of 1, it does not reset to 0 and will continue to be 1 for all following observations regardless of whether the condition is met or not.
How might I be able to implement a code that will let me given cond# a value of 1 or 0 based on checking each variable in their respective arrays? Am I incorrectly using the if/then function?
Thanks for any help or ideas you have.
data sample;
input var1 $ var2 $ var3 $ var4 $ x1 $ x2 $ x3 $ x4 $;
datalines;
a b c d 9 8 7 6
b c d e 8 7 6 5
c d e f 7 6 5 4
d e f g 6 5 4 3
e f g h 5 4 3 2
f g h i 4 3 2 1
g h i j 3 2 1 0
;
run;
data want;
set sample;
cond1=^^findc(cats(of var:),'ef');
cond2=^^findc(cats(of x:),'72');
run;
@novinosrin wrote:
data sample; input var1 $ var2 $ var3 $ var4 $ x1 $ x2 $ x3 $ x4 $; datalines; a b c d 9 8 7 6 b c d e 8 7 6 5 c d e f 7 6 5 4 d e f g 6 5 4 3 e f g h 5 4 3 2 f g h i 4 3 2 1 g h i j 3 2 1 0 ; run; data want; set sample; cond1=^^findc(cats(of var:),'ef'); cond2=^^findc(cats(of x:),'72'); run;
And I think@novinosrin wins obfuscation code of the day.
For our OP the FINDC function returns either the number position of the character found or 0. The second ^ (meaning NOT) negates the value of the number returned. Any 0 becomes 1 and any value returned other than 0 becomes 1 in the way SAS does logic operations. Then the first ^ negates the other result switching 0 to 1 and 1 to 0 as needed.
I like it.
Then the
Thank you @ballardw Sir. It's always been a privilege to have learned/learn a lot from you. I have sought your help numerous times and you must be glad I pay sincere attention. Thank you again
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.