Hi,
I need help coding a condition. I have four numeric fields and I want to say if any one is zero then do a certain action. Data looks like this:
A B C D
1 0 0 2
3 1 2 0
4 2 8 4
0 6 1 9
I want to say if these fields contain one zero then do this, two zeros then do that action. I know we can do it by making all possibilities one after another like If A = 0 and b ne 0 and c ne 0 and d ne 0 but wanted to know whether there is any other way to avoid all that code.
Thanks in advance for the help.
-Akber.
I had much the same idea but using the sum function. Your 1* are redundant and will add to the processing time.
Data want ;
Set have ;
X = Sum ((A = 0), (B = 0), (C = 0), (D = 0)) ;
Select (X) ;
When (1)
Do ;
/* Action when 1 zero */
End ;
When (2)
Do ;
/* Action when 2 zeros */
End ;
When (3)
Do ;
/* Action when 3 zeros */
End ;
Otherwise
Do ;
/* Action when no zeros */
End ;
End ;
Run ;
A B C D X
1 0 0 2 2
3 1 2 0 1
4 2 8 4 0
0 6 1 9 1
Richard in Oz
The variable NUM in the following step will contain the number of variables with a value of 0.
data want;
input A B C D;
num = 1*(a=0)
+1*(b=0)
+1*(c=0)
+1*(d=0);
put num=;
datalines;
1 0 0 2
3 1 2 0
4 2 8 4
0 6 1 9
run;
I had much the same idea but using the sum function. Your 1* are redundant and will add to the processing time.
Data want ;
Set have ;
X = Sum ((A = 0), (B = 0), (C = 0), (D = 0)) ;
Select (X) ;
When (1)
Do ;
/* Action when 1 zero */
End ;
When (2)
Do ;
/* Action when 2 zeros */
End ;
When (3)
Do ;
/* Action when 3 zeros */
End ;
Otherwise
Do ;
/* Action when no zeros */
End ;
End ;
Run ;
A B C D X
1 0 0 2 2
3 1 2 0 1
4 2 8 4 0
0 6 1 9 1
Richard in Oz
Or, a third approach:
data have;
input A B C D;
cards;
1 0 0 2
3 1 2 0
4 2 8 4
0 6 1 9
;
data want (drop=_:);
set have;
set have (rename=(A=_A b=_b c=_c d=_d));
array _x _a--_d;
do over _x;
_x=_x=0;
end;
number_of_zeros=sum(of _x(*));
run;
A slightly briefier third approach:
data want;
set have;
array x _numeric_;
number_of_zeros=0;
do over x;
number_of_zeros+x=0;
end;
run;
Haikuo
Haikuo,
Let's add one more reduction .. remove the need to initialize number_of_zeros:
data want;
set have;
array x _numeric_;
do over x;
number_of_zeros=sum(number_of_zeros,x=0);
end;
run;
@RichardinOz I like the use of the SUM function over my statement. Much cleaner code.
Thanks Art. It's a case of 'spot the obvious mistake' because I left out the condition
When (4)
Do ;
/* Action when 4 zeros */
End ;
BTW the 1* construct is a hangover from very old coding practices and superseded by the use of, for example, LENGTH statements to specify numeric variables, or the INPUT() function to manage type conversions.
Richard in Oz
The more, the merrier, hence the fourth approach:
data have;
input A B C D;
cards;
1 0 0 2
3 1 2 0
4 2 8 4
0 6 1 9
;
data want;
set have;
numberof0=lengthn(cats(of _all_))-lengthn(compress(cats(of _all_),'0'));
run;
proc print;run;
Haikuo
Here's a more obscure exception.
options missing='0';
data test;
a=1;
b=2;
c=.;
d=4;
combined = cats(of _all_);
put combined=;
run;
Because of the OPTION setting, missing values get converted to "0" in the combined string.
Oops. True. Crying for morning coffee! Haikuo
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.