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

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

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       

N.B. Behav.dur.s = временной интервал (в секундах) между «Behav.start» и «Behav.end»

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

Затем я попытался (но не смог ..) реструктурировать свою исходную вкладку фрейма данных, чтобы получить новый фрейм данных, такой как строка, поведение которой длится более часа (Behav.dur.s> 3600) и заменен на n «дублированных» строк с заданным поведением продолжительностью 1 час, обновляя Behav.start, Behav.end и Behav.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 Ответ

0 голосов
/ 28 марта 2019

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

Допущения

  • Время начинается в формате строки HH:MM после публикации;
  • Диапазон времени только в пределах один один день (т. Е.время в полночь от 00:00 до 23:59 одного дня).В противном случае разделить на день и rbind вместе;
  • Данные на вкладке 1017 * имеют разумный размер, поскольку перекрестное соединение добавит (до поднабора) 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 & 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
    
...