Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

sas

sas-iml

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:

  • all(x<0) would give the output FALSE
  • all(y<0) would give the output TRUE

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

like image 545
MWw Avatar asked Mar 20 '18 01:03

MWw


2 Answers

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;
like image 150
Joe Avatar answered Nov 13 '22 06:11

Joe


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

like image 26
Tom Avatar answered Nov 13 '22 07:11

Tom