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

Hello! I am trying to create the "want" column.

 

venuefruitnumberwant
marketapple312
marketorange29
marketbanana77
storeapple411
storeorange17
storebanana66

 

For the first entry, it first sums the number of apples, oranges, and bananas (for the market venue).

For the second entry it sums the oranges and bananas (for the market venue).

And the third entry sums the bananas (for the market venue).

 

This process then repeats for each type of venue.

 

Thanks in advance for the help!

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

Simple double DO loop:

data want;
do until (last.venue);
  set have;
  by venue;
  want = sum(want,number);
end;
do until (last.venue);
  set have;
  by venue;
  output;
  want = sum(want,-number);
end;
run;

View solution in original post

7 REPLIES 7
Quentin
Super User

What code have you tried?

 

It looks like if you reverse the sort order, WANT is a running sum of NUMBER.

BASUG is hosting free webinars ! Check out our recordings of past webinars: https://www.basug.org/videos. Be sure to subscribe to our email list for notification of future BASUG events.
yabwon
Onyx | Level 15

Try double DoW-loop, of course I assume data are properly sorted:

data Have;
  input venue	$ fruit	$ number want;
cards;
market	apple	3	12
market	orange	2	9
market	banana	7	7
store	apple	4	11
store	orange	1	7
store	banana	6	6
run;


data Want;
  sum = 0;
  do _N_ = 1 by 1 until(last.venue);
    set have(drop = want);
    by venue;
    sum + number;
  end;


  do _N_ = 0 to _N_ - 1;
    set have(drop = want);

    ln = lag(number);

    if _N_ then want = want - ln;
           else want = sum;
    output;
  end;

  keep venue fruit number want;
run;

 

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



Astounding
PROC Star

@yabwon 

 

Good approach.  Consider simplifying the bottom loop:

 

want = sum;

output;

sum = sum - number;

Reeza
Super User

Reverse running sum. Weird way to do it. 

1. Either reverse the data, calculate a running total and then reverse again. 

2. Calculate an overall total by venue, merge it in and subtract as you go down the rows. 

 

FYI - since order seems to matter here, I would have expected an order variable of some sort? Is it just alphabetical for fruit? Different orders will obviously change the resuts so something to think about. 

proc sql;
create table want as
select *, sum(number) as total, calculated total - number as want
from have
group by venue;
quit;


@Cruiser13 wrote:

Hello! I am trying to create the "want" column.

 

venue fruit number want
market apple 3 12
market orange 2 9
market banana 7 7
store apple 4 11
store orange 1 7
store banana 6 6

 

For the first entry, it first sums the number of apples, oranges, and bananas (for the market venue).

For the second entry it sums the oranges and bananas (for the market venue).

And the third entry sums the bananas (for the market venue).

 

This process then repeats for each type of venue.

 

Thanks in advance for the help!


 

mkeintz
PROC Star

If

  1. The data are grouped (but not necessarily in ascending or descending order) by venue.
  2. Each venue has exactly three fruits, with apple followed by orange followed by banana, then:
data have;
  input venue $ fruit $ number     x;
datalines;
market	apple	3	12
market	orange	2	9
market	banana	7	7
store	apple	4	11
store	orange	1	7
store	banana	6	6
run;


data want;
  set have;
  by venue notsorted;
  want+number;   /*Make the total for the venue */

  /* At end of venue, reread and output records*/
  if last.venue then do until (last.venue);
    set have;          
    by venue notsorted;
    output;
    want=want-number;  
  end;
run;

I read in your desired resulting values as variable X, and replicated by calculating variable WANT.  

 

Each venue is read twice.   Note that the first pass increments WANT, and at the end of the first pass, the second pass is programmed in a DO group, initiated by the statement.

  if last.venue then do until (last.venue);

In this statement the first "last.venue" is tracking the first pass of the venue, but the second "last.venue" is associated with the second pass - i.e. the second SET and BY statements.  

 

 

Eddited addtion.  This program also solves the more general problem as stated in your subject line, i.e. the first obs sums the entire venue, the 2nd obs sums entire venue minus the first obs.   And the i'th obs sum the entire venue except for obs 1 through i-1.  You then presumablhy wouldn't have to worry about the order or number of fruits.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
Kurt_Bremser
Super User

Simple double DO loop:

data want;
do until (last.venue);
  set have;
  by venue;
  want = sum(want,number);
end;
do until (last.venue);
  set have;
  by venue;
  output;
  want = sum(want,-number);
end;
run;
s_lassen
Meteorite | Level 14

You will have to read the data twice, e.g.:

data want;
  want=0;
  do until(last.venue);
    set have;
    by venue;
    want+number;
    end;
  do until(last.venue);
    set have;
    by venue;
    output;
    want+-number; /* subtract after outputting */
    end;
run;
  

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 7 replies
  • 665 views
  • 12 likes
  • 8 in conversation