基于R(dplyr、stringr、lubridate)中的多个半复杂过滤条件创建列
我有一个数据集,df基于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
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)