我有这样一个数据:
data<-data.frame(time=c(20230404001040, 20230404001050,20230404001100, 20230404001110, 20230404001120,20230404001130,
20230404001140,20230404001150,20230404001200),
on=c("FALSE", "FALSE", "FALSE", "TRUE","TRUE","TRUE","FALSE","FALSE","FALSE"))
'time' 写成 ymd_hms 表示。我觉得我可以用
data[,1] <- ymd_hms(data[,1])
。
如果on
为FALSE,表示开关关闭。
如果on
为TRUE,则表示开关已打开。
我想计算每个开/关事件的持续时间。
time
的每一行是 10 秒的间隔。所以我可以计算每个开/关事件中有多少行并乘以 10。所以我想要的输出应该是这样的:
data<-data.frame(time=c(20230404001040, 20230404001050,20230404001100, 20230404001110, 20230404001120,20230404001130,
20230404001140,20230404001150,20230404001200),
on=c("FALSE", "FALSE", "FALSE", "TRUE","TRUE","TRUE","FALSE","FALSE","FALSE"),
time_after_switch=c(0,10,20,0,10,20,0,10,20))
对于我的
data
前 3 行是关闭事件,接下来的 3 行是打开事件,最后 3 行是关闭事件。所以我可以认为它是 3 个周期。在每个周期内,持续时间为 0、10、20、0、10、20、0、10、20。我想让r代码计算time_after_switch
的值。
一种方法(使用日志条目之间的实际时间跨度):
## helper function to uniquely label blocks
## of continuous state for later groupwise
## duration summing:
get_block_labels <- function(xs){
rls <- rle(xs)$lengths
rep(1:length(rls), times = rls)
}
data |>
arrange(time) |>
mutate(time = time |> as.character() |> ymd_hms(),
dt = (time - lag(time, default = time[1])) |> as.integer(),
block = get_block_labels(on)
) |>
group_by(block) |>
mutate(dur = cumsum(dt))
输出:
+ # A tibble: 9 x 5
# Groups: block [3]
time on dt block dur
<dttm> <chr> <int> <int> <int>
1 2023-04-04 00:10:40 FALSE 0 1 0
2 2023-04-04 00:10:50 FALSE 10 1 10
3 2023-04-04 00:11:00 FALSE 10 1 20
4 2023-04-04 00:11:10 TRUE 10 2 10
5 2023-04-04 00:11:20 TRUE 10 2 20
6 2023-04-04 00:11:30 TRUE 10 2 30
7 2023-04-04 00:11:40 FALSE 10 3 10
8 2023-04-04 00:11:50 FALSE 10 3 20
9 2023-04-04 00:12:00 FALSE 10 3 30