MWw
MWw

Reputation: 160

Does SAS have a equivalent function to all() or any() in R

In R you can perform a condition across all rows in a column variable by using the all() or any() function. Is there an equivalent method in SAS?

I want condition if ANY rows in column x are negative, this should return TRUE.

Or, if ALL rows in column y are negative, this should return TRUE.

For example

x   y
-1  -2
2   -4
3   -4
4   -3

In R:

I wish to replicate the same column-wise operation in SAS.

Upvotes: 7

Views: 2416

Answers (3)

Joe
Joe

Reputation: 63424

For completeness' sake, here is the SAS-IML solution. Of course, it's trivial as the any and all functions exist by the same name... I also include an example of using loc to identify the positive elements.

data have ;
  input x y @@;
cards;
1 2 
2 4 
3 -4 
4 -3 
;
run;

proc iml;
    use have;
    read all var {"x" "y"};
    print x y;
    x_all = all(x>0);
    x_any = any(x>0);
    y_all = all(y>0);
    y_any = any(y>0);
    y_pos = y[loc(y>0)];

    print x_all x_any y_all y_any;
    print y_pos;
quit;

Upvotes: 8

Joe
Joe

Reputation: 63424

SQL is probably the most feels-like similar way to do this, but the data step is just as efficient, and lends itself a bit better to any sort of modification - and frankly, if you're trying to learn SAS, is probably the way to go simply from the point of view of learning how to do things the SAS way.

data want;
  set have end=eof;
  retain any_x all_x;         *persist the value across rows;
  any_x = max(any_x, (x>0));  *(x>0) 1=true 0=false, keep the MAX (so keep any true);
  all_x = min(all_x, (x>0));  *(x>0) keep the MIN (so keep any false);
  if eof then output;         *only output the final row to a dataset;
  *and/or;
  if eof then do;             *here we output the any/all values to macro variables;
    call symputx('any_x',any_x); *these macro variables can further drive logic;
    call symputx('all_x',all_x); *and exist in a global scope (unless we define otherwise);
  end;
run;

Upvotes: 7

Tom
Tom

Reputation: 51611

If you want to operate on all observations that might be easiest to do using SQL summary functions.

SAS will evaluate boolean expressions as 1 for true and 0 for false. So to find out if any observation has a condition you want to test if the MAX( condition ) is true (ie equal to 1). To find out if all observations have the condition you want to test if the MIN( condition ) is true.

data have ;
  input x y @@;
cards;
-1 -2 2 -4 3 -4 4 -3 
;

proc sql ;
create table want as 
  select 
     min(x<0) as ALL_X
   , max(x<0) as ANY_X
   , min(y<0) as ALL_Y
   , max(y<0) as ANY_Y
  from have
;
quit;

Result

Obs    ALL_X    ANY_X    ALL_Y    ANY_Y
 1       0        1        1        1

Upvotes: 7

Related Questions