SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
turcay
Lapis Lazuli | Level 10

Hello everyone,

 

I would like to get smallest positive value in an array? Is there a way to do this?

 

Data Have;
Length Variable1 8 Variable2 8 Variable3 8 Variable4 8 Variable5 8 Variable6 8;
Infile Datalines Missover;
Input  Variable1 
Variable2 Variable3 Variable4 Variable5 Variable6;
Datalines;
5 3 1 -1 -3 -5
Run;

Data Want;
Set Have;
Array theArray {*} Variable:;
Do i =1 to 6;
MinVariable=Min(theArray[i]);
End;
Run;

Thanks

10 REPLIES 10
turcay
Lapis Lazuli | Level 10

@SAS_inquisitiveMin(of theArray[i]); is still returning "-5", actually, I expect "1" instead of "-5", am I missing something?

 

Thank you

KachiM
Rhodochrosite | Level 12

turcay:

 

This should work. For me in SUE, the firstsmall turns to be a missing value. Secondsmall is OK. Why firstsmall is missing?. It may be working for you. Check it and tell.

Data have;
Length Var1 8 Var2 8 Var3 8 Var4 8 Var5 8 Var6 8;
Infile Datalines Missover;
Input  Var1 - Var6;
Datalines;
5 3 1 -1 -3 -5
Run;

Data _null_;
   Set Have;
   firstsmall = .; secondsmall = .;
   Array k[*] Var:;
   firstsamll  = smallest(1, of k[*]);
   secondsmall = smallest(2, of k[*]);
   put firstsmall = ;
   put secondsmall = ;
stop;
Run;
turcay
Lapis Lazuli | Level 10

Thanks a lot @KachiM,

 

But it returns missing either for my environment.

Norman21
Lapis Lazuli | Level 10

A similar question was asked here:

 

https://communities.sas.com/t5/SAS-Procedures/The-smallest-positive-value-for-each-variable/td-p/520...

 

You might be able to make use of that solution.

Norman.
SAS 9.4 (TS1M6) X64_10PRO WIN 10.0.17763 Workstation

Astounding
PROC Star

Trying not to overcomplicate this too much:

 

do I=1 to 6;

   if theArray{I} > 0 then do;

      if minVal = . or theArray{I} < minVal then minVal = theArray{I};

   end;

end;

Ksharp
Super User

Add one more condition.

 

Data Have;
Length Variable1 8 Variable2 8 Variable3 8 Variable4 8 Variable5 8 Variable6 8;
Infile Datalines Missover;
Input  Variable1 
Variable2 Variable3 Variable4 Variable5 Variable6;
Datalines;
5 3 1 -1 -3 -5
Run;

Data Want;
Set Have;
Array theArray {*} Variable:;
Do i =1 to 6;
 if sign(theArray[i]) ne -1 then MinVariable=Min(MinVariable,theArray[i]);
End;
Run;
turcay
Lapis Lazuli | Level 10

Thank you all of them, I have many solution to find smallest positive value in an array. But I want to ask related question about this to you @Ksharp @KachiM @Astounding @Norman21.

 

In User Defined Logic, when I try to use Min function for my array, it returns this -> ERROR: The function MIN requires at least 2 arguments. There are too few arguments for the function MIN.  MinFraction=Min(FractionOfQuarter[i]); works for SAS Base platform, but not for UDL, I want to get minimum value for between whole array values, how can I get it? Any suggestion?

 

 

Do i=1 To 9;     
FractionOfQuarter[i]=Datdif(_cashflow_.Balance.matdate[i],_date_, 'ACT/360')/90; /*It works*/ 
MinFraction=Min(FractionOfQuarter[i]);/*It returns -> ERROR: The function MIN requires at least 2 arguments. There are too few arguments for the function MIN.*/
End;

 

turcay
Lapis Lazuli | Level 10

Okay,

 

It seems it works when I type the following;

 

MinFraction=Min(of FractionOfQuarter[*]);

Thanks 🙂

KachiM
Rhodochrosite | Level 12

turcay:

 

I missed to see the positive minimum in your requirement. Hence, smallest() function is not appropriate. There are two ways I can solve it.

[1] By comparing each positive number, and finding the minimum at the same time.

[2] Copying positive numbers to a nee array, and use smallest() function on the new array.

 

Both are shown below. Your query to those who have answered you  on MinFraction=Min(FractionOfQuarter[i]);

is not understandable as the context is not known.

 

Here comes the code:

 

Data have;
Length Var1 8 Var2 8 Var3 8 Var4 8 Var5 8 Var6 8;
Infile Datalines Missover;
Input  Var1 - Var6;
Datalines;
5 3 1 -1 -3 -5
Run;

Data _null_;
   Set have;
   Array k[*] Var:;
   do i = 1 to dim(k);
      if k[i] >= 0 then Min = Min(Min, k[i]);
   end;
   put min = ;
Run;

data _null_;
   set have;
   array k[*] Var:;
   array new[6] _temporary_;
   j = 1;
   do i = 1 to dim(k);
      if k[i] >= 0 then do; new[j] = k[i]; j + 1; end;
   end;
   firstmin = smallest(1, of new[*]);
   put firstmin = ;
run;
ballardw
Super User

@KachiM smallest will work, just need to look at it a bit differently:

 

data want;
   set have;
   array k[*} var:  ;
   do i = 1 to dim(k);
      if smallest(i,of k(*)) ge 0 then do;
         val = smallest(i,of k(*));
         leave;;
      end;
   end;

run;

 

I will not make any claim to efficiency other than short code.

Notice that i will, if a positive value is found have, the index of the smallest positive value in the array which may be helpful.

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 10 replies
  • 5954 views
  • 1 like
  • 6 in conversation