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

Hi,

My requirement is i want to display max1 and max2 values from each group using grouping in datastep. Here is my dataset:

 

data devil;
infile datalines dlm=' ' dsd;
input pincode order num_total ;
datalines;
12345 1 99
23451 1 1
34512 1 10
45123 2 10
51234 2 13
67890 2 10
78901 3 11
89012 3 10
90123 3 20
;
run;

 

Expected output:

pincode  order num_total

12345 1 99
34512 1 10

51234 2 13
45123 2 10
67890 2 10

90123 3 20
78901 3 11

1 ACCEPTED SOLUTION

Accepted Solutions
PeterClemmensen
Tourmaline | Level 20

Here is one way. But why do you want to use a data step?

 

data devil;
infile datalines dlm=' ' dsd;
input pincode order num_total ;
datalines;
12345 1 99
23451 1 1
34512 1 10
45123 2 10
51234 2 13
67890 2 10
78901 3 11
89012 3 10
90123 3 20
;
run;

proc rank data=devil descending out=temp ties=dense;
   by order;
	var num_total;
   ranks rank;
run;

data want(drop=rank);
   set temp;
   where rank in (1,2);
run;

View solution in original post

9 REPLIES 9
PaigeMiller
Diamond | Level 26
proc sort data=devil;
    by order descending num_total;
run;

data want;
    set devil;
    by order;
    if first.order then seq=0;
    seq+1;
    if seq<=2;
run;

This may or may not handle ties the way you want, but you didn't really say what you want to do in the case of ties.

--
Paige Miller
PeterClemmensen
Tourmaline | Level 20

Here is one way. But why do you want to use a data step?

 

data devil;
infile datalines dlm=' ' dsd;
input pincode order num_total ;
datalines;
12345 1 99
23451 1 1
34512 1 10
45123 2 10
51234 2 13
67890 2 10
78901 3 11
89012 3 10
90123 3 20
;
run;

proc rank data=devil descending out=temp ties=dense;
   by order;
	var num_total;
   ranks rank;
run;

data want(drop=rank);
   set temp;
   where rank in (1,2);
run;
KachiM
Rhodochrosite | Level 12

Another Data Step Version. This solution can work for more than 3 observations in each Group. Sorting is made to sort by ORDER and in descending order of NUM_TOTAL. It leads to choosing the first two observations giving the First Max and Second Max.

 

data devil;
input pincode order num_total ;
datalines;
12345 1 99
23451 1 1
34512 1 10
45123 2 10
51234 2 13
67890 2 10
78901 3 11
89012 3 10
90123 3 20
;
run;


proc sort data = devil out = temp;
by order descending num_total ;
run;


data want;
   do i = 1 by 1 until(last.order);
      set temp;
      by order;
      if i in(1,2) then output;
   end;
drop i;
run;

Obs 	pincode 	order 	num_total
1 	12345 	1 	99
2 	34512 	1 	10
3 	51234 	2 	13
4 	45123 	2 	10
5 	90123 	3 	20
6 	78901 	3 	11
yabwon
Amethyst | Level 16

Hi,

I think that to handle the "order=2" case you have to change the datastep a little bit:

 

data want;
    
   _tmp_ = 0;
   do i = 1 by 1 until(last.order);
      set temp;
      by order descending num_total;
      _tmp_ + last.num_total;
      put _all_;
      if _tmp_ = 2 then _leave_ = i;
   end;
   put;
   put _all_;

   
   do i = 1 by 1 until(last.order);
      set temp;
      by order;
      if i <= _leave_ then output;
   end;

drop i _tmp_ _leave_;
run;

 

all the best

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



KachiM
Rhodochrosite | Level 12

Hi Bart,

 

Your suggestion gets 3 rows for ORDER = 2.  In this case, we get MAX1 = 13 and MAX2 = 10. The next value which is MAX3, is also 10. 

 

The OP is interested to get MAX1 and MAX2. Hence I stopped with the 2 values for each order.

 

If I missing to see what you are telling, kindly explain.

 

Regards,

DataSP

 

 

yabwon
Amethyst | Level 16

Hi DataSP,

 

I suggested the extension looking at OP's expected result. It looks like OP wants all results in case of ties.

 

all the best

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



KachiM
Rhodochrosite | Level 12

Hi Bart,

 

Somehow I missed OP's requirement for ties. The OP may use your suggested code for his requirements.

 

I tried to use one DO-LOOP to achieve such a result. So I have modified test data set to check for tie-conditions.

 

data devil;
input pincode order num_total ;
datalines;
12345 1 99
23451 1 1
34512 1 10
45123 2 10
51234 2 13
67890 2 10
78901 3 15
89012 3 15
90123 3 10
90123 3 10
90123 3  5
;
run;

proc sort data = devil out = temp;
by order descending num_total ;
run;

data want;
   t = 0;
   do until(last.order);
      set temp;
      by order;
      if t = 0 then do;
         t = num_total;
         count = 1;
         output;
      end;
      else if t = num_total then output;
      else if t > num_total then do;
         t = num_total;
         if count > 2 then leave;
         else if count = 1 then do; count + 1; output; end;
     end;
   end;
drop count t;
run;


Obs 	pincode 	order 	num_total
1 	12345 	1 	99
2 	34512 	1 	10
3 	51234 	2 	13
4 	45123 	2 	10
5 	67890 	2 	10
6 	78901 	3 	15
7 	89012 	3 	15
8 	90123 	3 	10
9 	90123 	3 	10

Best regards,

DataSP

PaigeMiller
Diamond | Level 26

Apparently, I missed the requirement about handling ties, which was not stated, but appears in the output clearly.

 

In that case, I endorse the solution by @PeterClemmensen using PROC RANK. I would not advise programming this yourself in a data step, it's already done for you in PROC RANK.

--
Paige Miller
Ksharp
Super User

data devil;
infile datalines dlm=' ' dsd;
input pincode order num_total ;
datalines;
12345 1 99
23451 1 1
34512 1 10
45123 2 10
51234 2 13
67890 2 10
78901 3 11
89012 3 10
90123 3 20
;
run;
proc sort data=devil out=temp;
by order descending num_total;
run;
data want;
 set temp;
 by order descending num_total notsorted;
 if first.order then n=0;
 if first.num_total then do;n+1;if n in (1 2) then output;end;
run;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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
  • 9 replies
  • 2065 views
  • 0 likes
  • 6 in conversation