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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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