Duplicate and edit rows to split datetime by day

Hi, I'm a beginner trying to replicate my pen and paper timetracking graph.

Each task should be a line occupying the time in which it occurred. My problem are tasks that occur between two days, I would want them to show on their day and start again in the next one.

Rplot


library(tidyverse)
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
  
df <- tibble(
          id = c(1,2,3,4),
          name = c("studying", "gaming", "studying", "gaming"),
          start = parse_datetime(c("2020-08-24T0900Z", "2020-08-24T1800Z", "2020-08-25T0900Z", "2020-08-25T1430Z")),
          end = parse_datetime(c("2020-08-24T1300Z", "2020-08-25T0100Z", "2020-08-25T1300Z", "2020-08-25T1930Z"))
)


ggplot(df) + geom_segment(
  aes(x = hour(start) + minute(start)/60,
      y = date(start),
      xend = hour(end) + minute(end)/60,
      yend = date(end),
      colour = name,
      size = 1
      )
)

I'm thinking duplicate problematic rows then change hour(end) to 23:59 in the first row and hour(start) to 00:00 in the second one, but I don't know how to do that.


library(tidyverse)
library(lubridate)
library(hms)
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union

df <- tibble(
  id = c(1,2,3,4),
  name = c("studying", "gaming", "studying", "gaming"),
  start = parse_datetime(c("2020-08-24T0900Z", "2020-08-24T1800Z", "2020-08-25T0900Z", "2020-08-25T1430Z")),
  end = parse_datetime(c("2020-08-24T1300Z", "2020-08-25T0100Z", "2020-08-25T1300Z", "2020-08-25T1930Z"))
)

(new_df <- mutate(df,
       difftime = 1L+difftime(as.Date(end),as.Date(start),units="days") %>% as.integer) %>% uncount(difftime) %>% 
  group_by(id) %>% mutate(first=ifelse(row_number()==1,TRUE,FALSE),
                          last=ifelse(row_number()==max(row_number()),TRUE,FALSE),
                          dpart = as.Date(start) + row_number() - 1 ,
                          t1 = if_else(first,hms::as_hms(start),hms::as_hms(0)),
                          t2 = if_else(last,hms::as_hms(end),hms::as_hms("23:59:59")),
                          s = as_datetime(paste0(dpart,"T",t1)),
                          e = as_datetime(paste0(dpart,"T",t2))))
ggplot(new_df) + geom_segment(
  aes(x = hour(s) + minute(s)/60,
      y = date(s),
      xend = hour(e) + minute(e)/60,
      yend = date(e),
      colour = name
      
  ),
  size = 4
)

2 Likes

Thank you so much, this worked perfectly.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.