littleworth
littleworth

Reputation: 5169

How to sum time accumulatively in R by interspersing with some time value

I have the following time data frame:

library(tidyverse)
tdat <- structure(list(tm = structure(c(108900, 105480, 110280), class = c("hms", 
"difftime"), units = "secs")), row.names = c(NA, -3L), class = c("tbl_df", 
"tbl", "data.frame"))
tdat

That looks like this:

 tdat
# A tibble: 3 x 1
  tm    
  <time>
1 30:15 
2 29:18 
3 30:38 

The value there are the minutes and second. What I want to do is to accumulatively sum the time but by adding 5 seconds in between. By hand it looks like this:

  30:15 
  00:05.  (30:15 + 00:05 = 30:20)
  29:18   (30:20 + 29:18 = 59:38)
  00:05.  (59:38 + 0:05  = 59:43)
  30:38   (59:43 + 30:38 = 1:30:21)

So the final vector or df we'd like to have is

 30:15 
 59:38
 1:30:21

How can we achieve that?

Upvotes: 0

Views: 62

Answers (1)

Jon Spring
Jon Spring

Reputation: 67000

We can convert to numeric, add 5, take the cumulative sum, and convert back to hms:

tdat %>%
  mutate(cuml = hms::as_hms(cumsum(as.numeric(tm)+5*60)))

# A tibble: 3 x 2
  tm     cuml  
  <time> <time>
1 30:15  30:20 
2 29:18  59:43 
3 30:38  90:26 

Edit: if you want the last row to leave out the extra 5 seconds, you could use:

tdat %>%
  mutate(cuml = hms::as_hms(cumsum(as.numeric(tm)+5*60) - if_else(row_number() == n(), 5*60, 0)))

Edit #2: I had not realized that the original source data was in Hours:Minutes, so I was surprised why the output showed 90:26 instead of 1:30:26. If we change the starting input to

tdat <- structure(list(tm = structure(c(108900, 105480, 110280)/60, 
                  class = c("hms", "difftime"), units = "secs")), 
                  row.names = c(NA, -3L), 
                  class = c("tbl_df", "tbl", "data.frame"))


 tm    
  <time>
1 30'15"
2 29'18"
3 30'38"

...then the output is as expected (after adjusting for 5 sec instead of 5 min, which should have tipped me off!):

> tdat %>%
+   mutate(cuml = hms::as_hms(cumsum(as.numeric(tm)+5)))
# A tibble: 3 x 2
  tm     cuml    
  <time> <time>  
1 30'15" 00:30:20
2 29'18" 00:59:43
3 30'38" 01:30:26

Upvotes: 1

Related Questions