BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
GS2
Obsidian | Level 7 GS2
Obsidian | Level 7

Using SAS 9.4

 

PRE_SL_W_countPost_SL_W_2wkPost_SL_W_6wkPRE_SL_E_countPost_SL_E_2wkPost_SL_E_6wkPRE_CL_W_countPost_CL_W_2wkPost_CL_W_6wkPRE_CL_E_countPost_CL_E_2wkPost_CL_E_6wk
888444888444
888044888444
889455899455
880550880550
888555888500

 

I have the above data and I want to find the minimum value (as long as it is greater than zero) in specific variables.

 

I have attempted the array below but I am not sure how to return values >0

 

data test2;
set have;

array min_SL_W {*} _numeric_ PRE_SL_W_count Post_SL_W_2wk Post_SL_W_6wk;
min = min(of min_SL_W[*]);

 

array min_SL_E {*} _numeric_ PRE_SL_E_count Post_SL_E_2wk Post_SL_E_6wk;
min2 = min(of min_SL_W[*]);

 

array min_CL_W {*} _numeric_ PRE_CL_W_count Post_CL_W_2wk Post_CL_W_6wk;
min3 = min(of min_CL_W[*]);

 

array min_CL_E {*} _numeric_ PRE_CL_E_count Post_CL_E_2wk Post_CL_E_6wk;
min4 = min(of min_CL_W[*]);
run;

 

Is there a good method to return only values >0 within each of the 4 variables groupings above? Thank you

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You might make your job of working with this data easier if you just converted the zeros to missing instead.

Do not include all numeric variables in each of your arrays. As you have it now you are counting including the three listed variables twice since that were already include as part of the _NUMERIC_ variable list.  In addition by having the array definition after you create the new minxx variables those new variables are being added into the _NUMERIC_ variable list once the compiler as seen that you have created them. So MIN2 is checking one more variable than MIN since it is also checking MIN.

And note that there is no need to add {*} or [*] to the ARRAY statement. When you list the actual names of the variables SAS can count how many there are.  You only need the [nnn] when you want SAS to make up names (or you are making a _temporary_ array).

data test2;
  set have;
  array min_SL_W  PRE_SL_W_count Post_SL_W_2wk Post_SL_W_6wk;
  array min_SL_E  PRE_SL_E_count Post_SL_E_2wk Post_SL_E_6wk;
  array min_CL_W  PRE_CL_W_count Post_CL_W_2wk Post_CL_W_6wk;
  array min_CL_E  PRE_CL_E_count Post_CL_E_2wk Post_CL_E_6wk;
  array all 
    PRE_SL_W_count Post_SL_W_2wk Post_SL_W_6wk
    PRE_SL_E_count Post_SL_E_2wk Post_SL_E_6wk
    PRE_CL_W_count Post_CL_W_2wk Post_CL_W_6wk
    PRE_CL_E_count Post_CL_E_2wk Post_CL_E_6wk
  ;
  do index=1 to dim(all);
    if all[index]=0 then all[index]=.;
  end;

  min1 = min(of min_SL_W[*]);
  min2 = min(of min_SL_W[*]);
  min3 = min(of min_CL_W[*]);
  min4 = min(of min_CL_W[*]);
run;

View solution in original post

3 REPLIES 3
JeffMaggio
Obsidian | Level 7

You could loop through the arrays and return the min greater than 0 with something like:

data test2;
set have;

array min_SL_W{*} _numeric_ PRE_SL_W_count Post_SL_W_2wk Post_SL_W_6wk;
min1 = 0;
do i =1 to dim(min_SL_W);
  if min_SL_W{i} < min1 and min_SL_W{i} ne 0 then min1 = min_SL_W{i};
end;
if min1=0 then min1=.;

...
repeat for each array
...


run;

 

Reeza
Super User

Maybe use the SMALLEST() function instead. You're looping until you find the smallest values that is not 0. 

 

data want;
set have;

array vars(*) var1-var20;

min_value=0;
i=0;

*check that any value is over 0 before starting. Not required but good idea;

if max(of vars(*))>0 then do while(min_value=0);
i+1;
if smallest(i, of vars(*)) >0 then min_value = smallest(i, of vars(*));
end;

run;
Tom
Super User Tom
Super User

You might make your job of working with this data easier if you just converted the zeros to missing instead.

Do not include all numeric variables in each of your arrays. As you have it now you are counting including the three listed variables twice since that were already include as part of the _NUMERIC_ variable list.  In addition by having the array definition after you create the new minxx variables those new variables are being added into the _NUMERIC_ variable list once the compiler as seen that you have created them. So MIN2 is checking one more variable than MIN since it is also checking MIN.

And note that there is no need to add {*} or [*] to the ARRAY statement. When you list the actual names of the variables SAS can count how many there are.  You only need the [nnn] when you want SAS to make up names (or you are making a _temporary_ array).

data test2;
  set have;
  array min_SL_W  PRE_SL_W_count Post_SL_W_2wk Post_SL_W_6wk;
  array min_SL_E  PRE_SL_E_count Post_SL_E_2wk Post_SL_E_6wk;
  array min_CL_W  PRE_CL_W_count Post_CL_W_2wk Post_CL_W_6wk;
  array min_CL_E  PRE_CL_E_count Post_CL_E_2wk Post_CL_E_6wk;
  array all 
    PRE_SL_W_count Post_SL_W_2wk Post_SL_W_6wk
    PRE_SL_E_count Post_SL_E_2wk Post_SL_E_6wk
    PRE_CL_W_count Post_CL_W_2wk Post_CL_W_6wk
    PRE_CL_E_count Post_CL_E_2wk Post_CL_E_6wk
  ;
  do index=1 to dim(all);
    if all[index]=0 then all[index]=.;
  end;

  min1 = min(of min_SL_W[*]);
  min2 = min(of min_SL_W[*]);
  min3 = min(of min_CL_W[*]);
  min4 = min(of min_CL_W[*]);
run;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 1778 views
  • 3 likes
  • 4 in conversation