计算条件累积时间

时间:2018-06-30 21:24:20

标签: r dplyr difftime

跟随this question的指针。

我想通过考虑它们各自的最后切换状态来计算所有Cat的累积时间。

EDIT: 我还想检查Toggle的第一个Cat状态是否为Off,如果是,对于特定的cat,它是从{{night} 1}},直到第一个FIRST Off时间应加到其总的条件累积打开时间中。

样本数据:

00:00:00

所需的样本输出:

       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

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

一个人可以使用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)

答案 1 :(得分:2)

使用基数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

答案 2 :(得分:1)

使用的可能解决方案:

# 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

或使用(仅原始问题):

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))
相关问题