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

I need to sum some total event times.

For example

 

Event Start Stop
a 1 10
b 8 12
c 16

20

 

Now if I wanted to sum the total time an event was occurring it would be days 1-12 and 16-20 as I want to not double count overlapping dates.

 

Now this could be done simply with the following code.

DATA part1;
  SET have;
  DO day=start to stop;
    OUTPUT;
   END;
RUN;
PROC SQL;
  CREATE TABLE want AS SELECT
  distinct(count(distinct(day)) as totaldays
  FROM part1;
QUIT;

However once we get to many events and many subjects the dataset in part1 can become very very large.  Is there a more elegant solution I am missing?

* There may be syntax errors in the code above, I am not bothered about that, it is just my typing out loud without running it.

1 ACCEPTED SOLUTION

Accepted Solutions
CurtisMackWSIPP
Lapis Lazuli | Level 10

This works:

 

data have;
infile datalines dsd dlm=",";
input Grp $	Event $	Start	Stop;
datalines;
X,a,1,10
X,b,8,12
X,c,16,20
X,d,1,10
Y,e,3,4
;
run;
 
DATA want(keep = grp totaldays);
  SET have;
  by grp;
  array days [1:100] _temporary_;
  DO day=start to stop;
    days(day) = 1;
  END;
  if last.grp then do;
    totaldays = sum(of days(*));
    output;
    call missing(of days(*));
  end;
RUN;

View solution in original post

4 REPLIES 4
CurtisMackWSIPP
Lapis Lazuli | Level 10

Your query is nothing more than

 

PROC SQL;
  CREATE TABLE want AS SELECT
  *,stop-start as totaldays
  FROM have;
QUIT;
SwissC
Obsidian | Level 7

@CurtisMackWSIPP 

Sorry no this would not work,I was not clear enough.

 

I want the sum of total days . In this case 17. (days 1,2,3,4,5,6,7,8,9,10,11,12,16,17,18,19,20). 

 

So as a better example

Grp Event Start Stop
X a 1 10
X b 8 12
X c 16 20
X d 1 10
Y e 3 4

 

Cleaning up the code some.

DATA part1;
  SET have;
  DO day=start to stop;
    OUTPUT;
   END;
RUN;
PROC SQL;
  CREATE TABLE want AS SELECT
  distinct grp, count(distinct(day)) as totaldays
  FROM part1
  GROUP BY grp;
QUIT;
Grp totaldays
X 17
Y 2
CurtisMackWSIPP
Lapis Lazuli | Level 10

This works:

 

data have;
infile datalines dsd dlm=",";
input Grp $	Event $	Start	Stop;
datalines;
X,a,1,10
X,b,8,12
X,c,16,20
X,d,1,10
Y,e,3,4
;
run;
 
DATA want(keep = grp totaldays);
  SET have;
  by grp;
  array days [1:100] _temporary_;
  DO day=start to stop;
    days(day) = 1;
  END;
  if last.grp then do;
    totaldays = sum(of days(*));
    output;
    call missing(of days(*));
  end;
RUN;
SwissC
Obsidian | Level 7
I like it! Using an array that way had never crossed my mind. Thank you.

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
  • 581 views
  • 2 likes
  • 2 in conversation