Как реструктурировать фрейм данных с разделением данных по времени через регулярные интервалы (и вычислить обновленные длительности)

#r #time #split #duration

#r #время #разделение #Продолжительность

Вопрос:

У меня есть фрейм данных, как показано ниже:

 tab <- data.frame(Behav = c("Rest","Eat","Eat"),      
              Behav.start= c("14:10:40","14:13:25","17:35:00"),
              Behav.end = c("14:13:24","17:31:05","17:37:25"), 
              Behav.dur.s = c("164","19060","145"))

Behav    Behav.start    Behav.end    Behav.dur.s
 Rest     14:10:40       14:13:24      164
 Eat      14:13:25       17:31:05      11860
 Eat      17:35:00       17:37:25      145       
  

Примечание. ‘Behavi.dur.s’ = интервал времени (в секундах) между ‘Behavi.start’ и ‘Behavi.end’

Я хочу вычислить почасовой бюджет времени, другими словами, я хочу вычислить, сколько времени человек потратил на отдых, прием пищи и т.д. В течение каждого интервала в 1 час.

Затем я попытался (но безуспешно ..) реструктурировать мою вкладку «Исходный фрейм данных», чтобы получить новый фрейм данных, такой как строка с поведением, длящимся более часа (Behavior.dur.s > 3600), заменяется на n «дублированных» строк с заданным поведением, длящимся с интервалом в 1 час, обновляя Behavior.start, Behavior.end и Behavior.dur.s

 Behav    Behav.start    Behav.end    Behav.dur.s
 Rest     14:10:40       14:13:24      164
 Eat      14:13:25       15:00:00      2795
 Eat      15:00:00       16:00:00      3600
 Eat      16:00:00       17:00:00      3600
 Eat      17:00:00       17:31:05      1865
 Eat      17:35:00       17:37:25      145 
  

Тогда я смогу рассчитать почасовой бюджет времени.

Я был бы действительно признателен за помощь, большое вам спасибо!

Ответ №1:

Рассмотрите следующие шаги с приведенными ниже допущениями, которые используют перекрестное объединение для всех 24 часов в сутках, затем подмножества с определенной продолжительностью и, наконец, повторно вычисляют начальные / конечные точки.

Предположения

  • Время берется в строковом формате HH:MM как указано;
  • Время варьируется только в пределах одного дня (т. е. от полуночи 00:00 до 23:59 одного дня). В противном случае разделить по дням и rbind вместе;
  • Данные на вкладке имеют разумный размер, поскольку перекрестное объединение добавит (перед подмножеством) 24 строки для каждой строки вкладки.

Шаги

  1. Построение / преобразование данных

     # CONVERT TIMES TO POSIXct TYPES
    tab <- within(tab, {
      Behav.start = as.POSIXct(Behav.start, tz="GMT", format="%H:%M:%S")
      Behav.end = as.POSIXct(Behav.end, tz="GMT", format="%H:%M:%S")
    })
    
    # BUILD DF OF ALL 24 HOURS DURATIONS FOR CURRENT DATE
    hours_df <- data.frame(start_hour = as.POSIXlt(as.POSIXct(Sys.Date())   c(0:23)*60*60),
                           end_hour = as.POSIXlt(as.POSIXct(Sys.Date())   c(1:24)*60*60))
      
  2. Перекрестное соединение подмножество

     mdf <- merge(tab, hours_df, all=TRUE)
    
    sdf <- subset(mdf, Behav.start <= end_hour amp; Behav.end >= start_hour)  
      
  3. Вычислить окончательное начало / конец

     final_df <- within(sdf, {
      final_start <- as.POSIXct(ifelse(Behav.start > start_hour, Behav.start, start_hour),
                                tz="GMT", origin="1970-01-01")
      final_end <- as.POSIXct(ifelse(Behav.end < end_hour, Behav.end, end_hour),
                              tz="GMT", origin="1970-01-01")
    
      final_dur <- as.numeric(difftime(final_end, final_start, units="secs"))
    
      rm(Behav.start, Behav.end, start_hour, end_hour, Behav.dur.s)
    
    })[c("Behav", "final_start", "final_end", "final_dur")]
    
    # CONVERT DATE/TIME TO STRING TIME
    final_df <- data.frame(within(final_df, {
       final_start <- format(final_start, format="%H:%M:%S")
       final_end <- format(final_end, format="%H:%M:%S")
    }), row.names = NULL)
    
    final_df
    #   Behav final_start final_end final_dur
    # 1  Rest    14:10:40  14:13:24       164
    # 2   Eat    14:13:25  15:00:00      2795
    # 3   Eat    15:00:00  16:00:00      3600
    # 4   Eat    16:00:00  17:00:00      3600
    # 5   Eat    17:00:00  17:31:05      1865
    # 6   Eat    17:35:00  17:37:25       145
      

Комментарии:

1. Большое спасибо за ваш подробный и аннотированный ответ! Это работает отлично 🙂

2. C’est parfait? Приятно слышать и рад помочь!

3. C’est parfait 😉