#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 строки для каждой строки вкладки.
Шаги
-
Построение / преобразование данных
# 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))
-
Перекрестное соединение подмножество
mdf <- merge(tab, hours_df, all=TRUE) sdf <- subset(mdf, Behav.start <= end_hour amp; Behav.end >= start_hour)
-
Вычислить окончательное начало / конец
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 😉