如何使用定期拆分的时间数据重组数据帧(并计算更新的持续时间)
How to restructure a data frame with time data split at regular interval (and compute updated durations)
我有如下数据框:
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) 是用持续 1 小时间隔的给定行为替换为 n 'duplicated' 行,更新 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
然后,我就能计算出每小时的时间预算。
非常感谢您的帮助,非常感谢!
在以下假设下考虑以下步骤,即在一天中的所有 24 小时内使用交叉联接,然后子集到特定持续时间,最后重新计算 start/end 点。
假设
- 时间源自发布的
HH:MM
字符串格式;
- 时间范围仅在 一天内(即一天中
00:00
到 23:59
午夜的时间)。否则按天拆分和 rbind
一起;
- tab 中的数据大小合理,因为交叉连接将为选项卡的 每个 行添加(在子集之前)24 行。
步骤
数据Build/Conversion
# 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 & Behav.end >= start_hour)
计算最终结果Start/End
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
我有如下数据框:
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) 是用持续 1 小时间隔的给定行为替换为 n 'duplicated' 行,更新 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
然后,我就能计算出每小时的时间预算。
非常感谢您的帮助,非常感谢!
在以下假设下考虑以下步骤,即在一天中的所有 24 小时内使用交叉联接,然后子集到特定持续时间,最后重新计算 start/end 点。
假设
- 时间源自发布的
HH:MM
字符串格式; - 时间范围仅在 一天内(即一天中
00:00
到23:59
午夜的时间)。否则按天拆分和rbind
一起; - tab 中的数据大小合理,因为交叉连接将为选项卡的 每个 行添加(在子集之前)24 行。
步骤
数据Build/Conversion
# 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 & Behav.end >= start_hour)
计算最终结果Start/End
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