R - 绘制重叠时间间隔

时间:2014-09-12 06:46:31

标签: r datetime plot

我有一份人员名单,以及他们一天的工作开始和结束时间。我想绘制一条曲线,显示当天任何一分钟工作的人员总数。我能做的就是为一天中的每一分钟添加1440个额外的条件布尔变量并总结它们,但这看起来非常不优雅。我想知道是否有更好的方法(积分?)。

以下是使用我的示例数据生成df的代码:

sample_wt <- function() {

    require(lubridate)

    set.seed(10)

    worktime <- data.frame(
            ID = c(1:100),
            start = now()+abs(rnorm(100,4800,2400))
            )

    worktime$end <- worktime$start + abs(rnorm(100,20000,10000))

    worktime$length <- difftime(worktime$end, worktime$start, units="mins")

    worktime
}

要创建示例数据,您可以执行以下操作:

DF <- sample_wt() 

3 个答案:

答案 0 :(得分:5)

这是使用Bioconductor中的IRanges包的一个选项。

library(IRanges)
## generate sample
DF <- sample_wt()
## create the range from the sample data
rangesA <- IRanges(as.numeric(DF$start), as.numeric(DF$end))
## create one minute range 
xx = seq(min(DF$start),max(DF$end),60)
rangesB <- IRanges(as.numeric(xx),as.numeric(xx+60))
## count the overlaps
ov <- countOverlaps(rangesB, rangesA, type="within")
## plot the result
plot(xx,ov,type='l')

enter image description here

答案 1 :(得分:1)

我没有安装lubridate,因此我通过Sys.time而非now生成了data.frame(猜测它们应该类似)。这可以解决问题:

    minutes<-seq(as.POSIXct(paste(sep="",Sys.Date()," 00:00:00")),by="min",length.out=24*60)
    rowSums(outer(minutes,worktime$start,">") & outer(minutes,worktime$end,"<"))

答案 2 :(得分:0)

当然可以改进,但这似乎可以做到:

time_range <- seq(min(DF$start), max(DF$end), 60)
result <- integer(length(time_range))
for (t in seq_along(time_range)) {
  result[t] <- sum(DF$start <= time_range[t] & DF$end >= time_range[t])
}