基于R(dplyr、stringr、lubridate)中的多个半复杂过滤条件创建列

基于R(dplyr、stringr、lubridate)中的多个半复杂过滤条件创建列,r,dplyr,tidyverse,lubridate,stringr,R,Dplyr,Tidyverse,Lubridate,Stringr,我有一个数据集,df Read Box ID Time T out 10/1/2019 9:00:01 AM T out 10/1/2019 9:00:02 AM T out 10/1/2019 9:00:03 AM T

我有一个数据集,df

 Read      Box       ID      Time                            
 T         out               10/1/2019 9:00:01 AM
 T         out               10/1/2019 9:00:02 AM             
 T         out               10/1/2019 9:00:03 AM            
 T         out               10/1/2019 9:02:59 AM             
 T         out               10/1/2019 9:03:00 AM
 F                           10/1/2019 9:05:00 AM
 T         out               10/1/2019 9:06:00 AM             
 T         out               10/1/2019 9:06:02 AM             
 T         in                10/1/2019 9:07:00 AM
 T         in                10/1/2019 9:07:02 AM
 T         out               10/1/2019 9:07:04 AM
 T         out               10/1/2019 9:07:05 AM             
 T         out               10/1/2019 9:07:06 AM             
 T         out    hello      10/1/2019 9:07:08 AM
 F         in                10/1/2019 9:08:10 AM
 F         in                10/1/2019 9:08:11 AM
 T         draft             10/2/2019 10:00:00 AM
 T         draft             10/2/2019 10:00:05 AM
 T         draft             10/2/2019 10:00:20 AM
 T         draft             10/2/2019 10:00:25 AM
 T         draft             10/2/2019 10:02:00 AM
 T         draft             10/2/2019 10:02:20 AM
基于此数据集中的某些条件,我想创建starttime列和endtime列

发生以下情况时,我希望创建“开始时间”: Read==“T”,Box==“out”或Box==“draft”,ID==“”

我希望在发生以下情况时创建“结束时间”: 当所需条件之间的间隔小于30秒时,读取==“T”,框==“out”或框==“草稿”,ID==“D”

当此条件的第一个实例发生时,将生成starttime。例如,对于该数据集,起始时间将为2019年1月10日9:00:01 AM,因为这是我们看到所需条件Read=T、Box=“out”或Box==“draft”和ID=“”

但是,当这些条件中的任何一个不正确时,或者如果时间戳之间的时间超过30秒,将创建endtime。例如,在第17行的以下位置创建starttime: 2019年10月2日上午10:00:00,将于2019年10月2日上午10:00:25在第20行创建结束时间

由于时间戳之间的时间超过30秒,下一个开始时间将在:2019年2月10日上午10:02:00创建。 我不确定我是否需要在代码中加入thresh来满足这个要求?我只是不知道如何实现这一点。 如有任何建议,我们将不胜感激

  starttime                    endtime                     duration

  10/1/2019 9:00:01 AM        10/1/2019 9:03:00 AM         179 secs
  10/1/2019 9:06:00 AM        10/1/2019 9:06:02 AM         2 secs
  10/1/2019 9:07:05 AM        10/1/2019 9:07:06 AM         1 secs
  10/2/2019 10:00:00 AM       10/2/2019 10:00:25 AM        25 secs
  10/2/2019 10:02:00 AM       10/2/2019 10:02:20 AM        20 secs
dput:

我还想将Box==“draft”以及>30秒的thresh合并到这段代码中

  library(dplyr)



  Thresh <- 30  (seconds)


  df1<-df %>%
  mutate(Time = lubridate::mdy_hms(Time), 
     cond = Read == "True" & Box == "out"|Box == "draft" & ID == "" , 
     grp = cumsum(!cond)) %>%
  filter(cond) %>%
  group_by(grp) %>%
  summarise(starttime = first(Time), 
        endtime = last(Time), 
        duration = difftime(endtime, starttime, units = "secs")) %>%
  select(-grp)
库(dplyr)
脱粒率%
过滤器(cond)%%>%
分组依据(grp)%>%
总结(开始时间=第一次),
结束时间=最后一次(时间),
持续时间=difftime(endtime,starttime,units=“secs”))%>%
选择(-grp)

在问题中给出的示例中,规则的应用方式似乎不一致。目前尚不清楚,当距离上次时间戳已过30秒时,这是否应标记新时段的开始或前一时段的结束。示例中使用了这两种方法

如果30秒过去了,我将假设一个新的周期开始,这意味着在此之前的最后一个有效时间戳标志着前一个周期的结束

此方法无需循环即可工作。它将时间分割为连续的“有效”时间(即符合标准的时间),如果间隔超过30秒,则进一步分割这些时间。然后,它只提取每个子组中的最小和最大时间

库(lubridate)

df$Time我不太明白你的逻辑。如果09:02:59是一个结束时间,因为距离上次时间戳已经超过30秒,为什么10:00:25是一个结束时间?你在这里应用规则的方式似乎不一致。如果距离上次时间戳超过30秒,您是开始新的持续时间,还是在这里结束上次持续时间?嗨@Allen,让我明天试试。为了回答你的问题,我之所以说10:00:25是一个结束时间,因为下一个时间戳是10:02:00,超过30秒。(从10:00:25到10:02:00超出了30秒的时间点,因此应该在这两个时间之间中断)此外,我很抱歉,9:03:00应该是结束时间。下一个时间戳是:9:00:00-9:00:02在我尝试之前,有没有办法调整您的代码?谢谢你,这对我帮助很大。(我想说的是,当间隔时间超过30秒时,它会“分裂”)@TanishaHudson我想如果你检查一下我发布的代码的数字和逻辑,它会完全符合你所描述的。如果没有,请准确描述结果的问题是什么,以及为什么它们与您期望的输出不匹配i@Allan您能看看我最近的问题吗?
  library(dplyr)



  Thresh <- 30  (seconds)


  df1<-df %>%
  mutate(Time = lubridate::mdy_hms(Time), 
     cond = Read == "True" & Box == "out"|Box == "draft" & ID == "" , 
     grp = cumsum(!cond)) %>%
  filter(cond) %>%
  group_by(grp) %>%
  summarise(starttime = first(Time), 
        endtime = last(Time), 
        duration = difftime(endtime, starttime, units = "secs")) %>%
  select(-grp)