Using SAS 9.4
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 |
8 | 8 | 8 | 4 | 4 | 4 | 8 | 8 | 8 | 4 | 4 | 4 |
8 | 8 | 8 | 0 | 4 | 4 | 8 | 8 | 8 | 4 | 4 | 4 |
8 | 8 | 9 | 4 | 5 | 5 | 8 | 9 | 9 | 4 | 5 | 5 |
8 | 8 | 0 | 5 | 5 | 0 | 8 | 8 | 0 | 5 | 5 | 0 |
8 | 8 | 8 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 0 | 0 |
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
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;
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;
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;
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 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.