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

Hi All,

 

I am looking for a solution to this problem using Datastep. Using SAS transform have dataset to want dataset. Output all observations with maximum price by item (do not remove duplicates).

 

have:

id

item

price

1

Apple

98

1

Apple

99

1

Apple

100

1

Apple

100

2

Banana

30

2

Banana

45

2

Banana

48

3

Orange

76

3

Orange

78

3

Orange

78

3

Orange

83

3

Orange

83

 

want:

id

item

price

1

Apple

100

1

Apple

100

2

Banana

48

3

Orange

83

3

Orange

83

 

Dataset code:

 

Data have;

input id item $ price;

datalines;

1 Apple 98

1 Apple 99

1 Apple 100

1 Apple 100

2 Banana 30

2 Banana 45

2 Banana 48

3 Orange 76

3 Orange 78

3 Orange 78

3 Orange 83

3 Orange 83

;

run;

proc print; run;

 

 

Solution using:

 

PROC SQL:

 

proc sql;

create table want as

select * from have as a

where id in (

select id from have as b

group by id

having max(b.price) = a.price

);

quit;

proc print; run;

 

 

I am looking for a solution using Datastep.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

You could also use Proc Rank.

Data have;
  input id item $ price;
  datalines;
1 Apple 98
1 Apple 99
1 Apple 100
1 Apple 100
2 Banana 30
2 Banana 45
2 Banana 48
3 Orange 76
3 Orange 78
3 Orange 78
3 Orange 83
3 Orange 83
;
proc rank data=have out=want(where=(rank=1)) ties=dense descending;
  by id;
  ranks rank;
  var price;
run;
proc print data=want;
run;

Patrick_0-1685153166372.png

 

View solution in original post

4 REPLIES 4
ballardw
Super User

Why a data step? "Groups of related values" really isn't the main strength of the data step. Data step is more for record by record processing.

 

It would likely be easier to use a Proc Sort before the data step. Note that "group by" is an implied sort behind the scenes in SQL.

 

 

A_Kh
Lapis Lazuli | Level 10
proc sort data=have;
    by id item descending price;
run; 
data want; 
	set have;
	by id item;
	retain temp;
	if first.item then temp=price;
	if price=temp;
proc print;run;
Patrick
Opal | Level 21

You could also use Proc Rank.

Data have;
  input id item $ price;
  datalines;
1 Apple 98
1 Apple 99
1 Apple 100
1 Apple 100
2 Banana 30
2 Banana 45
2 Banana 48
3 Orange 76
3 Orange 78
3 Orange 78
3 Orange 83
3 Orange 83
;
proc rank data=have out=want(where=(rank=1)) ties=dense descending;
  by id;
  ranks rank;
  var price;
run;
proc print data=want;
run;

Patrick_0-1685153166372.png

 

Kurt_Bremser
Super User

Use a double DO loop:

data want;
do until (last.item);
  set have;
  by id item;
  maxprice = max(maxprice,price);
end;
do until (last.item);
  set have;
  by id item;
  if price = maxprice then output;
end;
drop maxprice;
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!

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
  • 4 replies
  • 564 views
  • 5 likes
  • 5 in conversation