计算条件累计时间
Calculating conditional cumulative time
遵循 this question 的指示。
我想计算 所有 个 Cat
的累计时间,考虑它们各自的最后切换状态。
EDIT:
我还想检查 Cat
的第一个 Toggle
状态是否为 Off
,如果是,对于那个特定的 cat
,从午夜开始的时间 00:00:00
直到第一个 FIRST 关闭时间应添加到其总条件累积开启时间。
示例数据:
Time Cat Toggle
1 05:12:09 36 On
2 05:12:12 26R Off # First Toggle of this Cat happens to be Off, Condition met
3 05:12:15 26R On
4 05:12:16 26R Off
5 05:12:18 99 Off # Condition met
6 05:12:18 99 On
7 05:12:24 36 Off
8 05:12:26 36 On
9 05:12:29 80 Off # Condition met
10 05:12:30 99 Off
11 05:12:31 95 Off # Condition met
12 05:12:32 36 Off
所需的示例输出:
Cat Time(Secs)
1 36 21
2 26R 18733 # (=1+18732), 18732 secs to be added = total Sec from midnight till 05:12:12
3 99 18750 # (=12+18738), 18738 secs to be added = total Sec from midnight till 05:12:18
4 .. ..
感谢任何形式的帮助。
可以使用 as.difftime
函数将时间从 H:M:S
格式转换为秒。然后为每个 On
雕像找到 lead
记录,以计算从 On
开始的时间间隔。
library(dplyr)
# Convert Time in seconds.
df %>% mutate(Time = as.difftime(Time, units = "secs")) %>%
group_by(Cat) %>%
mutate(TimeInterVal = ifelse(Toggle == "On", (lead(Time) - Time), 0)) %>%
summarise(TimeInterVal = sum(TimeInterVal))
# # A tibble: 5 x 2
# Cat TimeInterVal
# <chr> <dbl>
# 1 26R 1.00
# 2 36 21.0
# 3 80 0
# 4 95 0
# 5 99 12.0
注意: 可以考虑在 Time
上安排数据确保行按时排序。
数据:
df <- read.table(text ="
Time Cat Toggle
1 05:12:09 36 On
2 05:12:12 26R Off
3 05:12:15 26R On
4 05:12:16 26R Off
5 05:12:18 99 Off
6 05:12:18 99 On
7 05:12:24 36 Off
8 05:12:26 36 On
9 05:12:29 80 Off
10 05:12:30 99 Off
11 05:12:31 95 Off
12 05:12:32 36 Off",
header = TRUE, stringsAsFactors = FALSE)
使用data.table的可能解决方案:
# load the 'data.table'-package, convert 'df' to a 'data.table'
# and 'Time'-column to a time-format
library(data.table)
setDT(df)[, Time := as.ITime(Time)]
# calculate the time-difference
df[, .(time.diff = sum((shift(Time, type = 'lead') - Time) * (Toggle == 'On'), na.rm = TRUE))
, by = Cat]
给出:
Cat time.diff
1: 36 21
2: 26R 1
3: 99 12
4: 80 0
5: 95 0
在评论中回复你的问题,你可以这样做:
# create a new data.table with midnigth times for the categories where
# the first 'Toggle' is on "Off"
df0 <- df[, .I[first(Toggle) == "Off"], by = Cat
][, .(Time = as.ITime("00:00:00"), Cat = unique(Cat), Toggle = "On")]
# bind that to the original data.table; order on 'Cat' and 'Time'
# and then do the same calculation
rbind(df, df0)[order(Cat, Time)
][, .(time.diff = sum((shift(Time, type = 'lead') - Time) * (Toggle == 'On'), na.rm = TRUE))
, by = Cat]
给出:
Cat time.diff
1: 26R 18733
2: 36 21
3: 80 18749
4: 95 18751
5: 99 18750
基于 R 的替代方案(仅原始问题):
df$Time <- as.POSIXct(df$Time, format = "%H:%M:%S")
stack(sapply(split(df, df$Cat),
function(x) sum(diff(x[["Time"]]) * (head(x[["Toggle"]],-1) == 'On'))))
给出:
values ind
1 1 26R
2 21 36
3 0 80
4 0 95
5 12 99
或用tidyverse(仅原始问题):
library(dplyr)
library(lubridate)
df %>%
mutate(Time = lubridate::hms(Time)) %>%
group_by(Cat) %>%
summarise(time.diff = sum(diff(Time) * (head(Toggle, -1) == 'On'),
na.rm = TRUE))
使用基数 R:
df$Time=as.POSIXct(df$Time,,"%H:%M:%S")
stack(by(df,df$Cat,function(x)sum(c(0,diff(x$Time))*(x$Toggle=="Off"))))
values ind
1 1 26R
2 21 36
3 0 80
4 0 95
5 12 99
遵循 this question 的指示。
我想计算 所有 个 Cat
的累计时间,考虑它们各自的最后切换状态。
EDIT:
我还想检查 Cat
的第一个 Toggle
状态是否为 Off
,如果是,对于那个特定的 cat
,从午夜开始的时间 00:00:00
直到第一个 FIRST 关闭时间应添加到其总条件累积开启时间。
示例数据:
Time Cat Toggle
1 05:12:09 36 On
2 05:12:12 26R Off # First Toggle of this Cat happens to be Off, Condition met
3 05:12:15 26R On
4 05:12:16 26R Off
5 05:12:18 99 Off # Condition met
6 05:12:18 99 On
7 05:12:24 36 Off
8 05:12:26 36 On
9 05:12:29 80 Off # Condition met
10 05:12:30 99 Off
11 05:12:31 95 Off # Condition met
12 05:12:32 36 Off
所需的示例输出:
Cat Time(Secs)
1 36 21
2 26R 18733 # (=1+18732), 18732 secs to be added = total Sec from midnight till 05:12:12
3 99 18750 # (=12+18738), 18738 secs to be added = total Sec from midnight till 05:12:18
4 .. ..
感谢任何形式的帮助。
可以使用 as.difftime
函数将时间从 H:M:S
格式转换为秒。然后为每个 On
雕像找到 lead
记录,以计算从 On
开始的时间间隔。
library(dplyr)
# Convert Time in seconds.
df %>% mutate(Time = as.difftime(Time, units = "secs")) %>%
group_by(Cat) %>%
mutate(TimeInterVal = ifelse(Toggle == "On", (lead(Time) - Time), 0)) %>%
summarise(TimeInterVal = sum(TimeInterVal))
# # A tibble: 5 x 2
# Cat TimeInterVal
# <chr> <dbl>
# 1 26R 1.00
# 2 36 21.0
# 3 80 0
# 4 95 0
# 5 99 12.0
注意: 可以考虑在 Time
上安排数据确保行按时排序。
数据:
df <- read.table(text ="
Time Cat Toggle
1 05:12:09 36 On
2 05:12:12 26R Off
3 05:12:15 26R On
4 05:12:16 26R Off
5 05:12:18 99 Off
6 05:12:18 99 On
7 05:12:24 36 Off
8 05:12:26 36 On
9 05:12:29 80 Off
10 05:12:30 99 Off
11 05:12:31 95 Off
12 05:12:32 36 Off",
header = TRUE, stringsAsFactors = FALSE)
使用data.table的可能解决方案:
# load the 'data.table'-package, convert 'df' to a 'data.table'
# and 'Time'-column to a time-format
library(data.table)
setDT(df)[, Time := as.ITime(Time)]
# calculate the time-difference
df[, .(time.diff = sum((shift(Time, type = 'lead') - Time) * (Toggle == 'On'), na.rm = TRUE))
, by = Cat]
给出:
Cat time.diff 1: 36 21 2: 26R 1 3: 99 12 4: 80 0 5: 95 0
在评论中回复你的问题,你可以这样做:
# create a new data.table with midnigth times for the categories where
# the first 'Toggle' is on "Off"
df0 <- df[, .I[first(Toggle) == "Off"], by = Cat
][, .(Time = as.ITime("00:00:00"), Cat = unique(Cat), Toggle = "On")]
# bind that to the original data.table; order on 'Cat' and 'Time'
# and then do the same calculation
rbind(df, df0)[order(Cat, Time)
][, .(time.diff = sum((shift(Time, type = 'lead') - Time) * (Toggle == 'On'), na.rm = TRUE))
, by = Cat]
给出:
Cat time.diff 1: 26R 18733 2: 36 21 3: 80 18749 4: 95 18751 5: 99 18750
基于 R 的替代方案(仅原始问题):
df$Time <- as.POSIXct(df$Time, format = "%H:%M:%S")
stack(sapply(split(df, df$Cat),
function(x) sum(diff(x[["Time"]]) * (head(x[["Toggle"]],-1) == 'On'))))
给出:
values ind 1 1 26R 2 21 36 3 0 80 4 0 95 5 12 99
或用tidyverse(仅原始问题):
library(dplyr)
library(lubridate)
df %>%
mutate(Time = lubridate::hms(Time)) %>%
group_by(Cat) %>%
summarise(time.diff = sum(diff(Time) * (head(Toggle, -1) == 'On'),
na.rm = TRUE))
使用基数 R:
df$Time=as.POSIXct(df$Time,,"%H:%M:%S")
stack(by(df,df$Cat,function(x)sum(c(0,diff(x$Time))*(x$Toggle=="Off"))))
values ind
1 1 26R
2 21 36
3 0 80
4 0 95
5 12 99