2014-09-12 40 views
8

Tôi có danh sách người và thời gian bắt đầu và kết thúc làm việc của họ trong một ngày. Tôi muốn vẽ một đường cong cho thấy tổng số người làm việc tại bất kỳ phút nào trong ngày. Những gì tôi có thể làm là chỉ cần thêm 1440 biến boolean có điều kiện bổ sung cho mỗi phút trong ngày và tổng hợp chúng, nhưng điều đó có vẻ rất không phù hợp. Tôi tự hỏi nếu có một cách tốt hơn để làm điều đó (tích phân?).R - khoảng thời gian chồng chéo âm mưu

Dưới đây là đoạn code để tạo ra một df với dữ liệu mẫu của tôi:

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 
} 

Để tạo dữ liệu mẫu, bạn có thể làm điều gì đó như:

DF <- sample_wt() 
+0

Đây không phải là dữ liệu mẫu, nó là một hàm. –

+1

@Pascal yes, một hàm có thể được sử dụng để tạo dữ liệu phong phú. – agstudy

+0

@agstudy OP không cung cấp cách sử dụng. –

Trả lời

5

đây một lựa chọn sử dụng IRanges gói từ Bioconductor .

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

+0

Tôi nghĩ rằng có lỗi trong dòng mã thứ ba, phải là: 'rangeA < - IRanges (as.numeric (DF $ bắt đầu), as.numeric (DF $ end)) '(DF thay vì rangeA) –

+0

@arumbay yes thanks. Tôi sửa lỗi đánh máy. – agstudy

+0

Tôi không thể tìm thấy hàm 'sample_wt'. Từ đó gói là gì? –

0

Chắc chắn nó có thể được cải thiện, nhưng điều này dường như để làm điều đó:

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]) 
} 
1

Tôi không có lubridate cài đặt, vì vậy tôi đã đưa ra data.frame qua Sys.time thay của now (đoán chúng phải giống nhau). Điều này có thể làm cho thủ thuật:

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,"<")) 
+0

Đẹp nhất! Tôi thích nó nhiều hơn tôi thích của tôi, và 'microbenchmark' nói rằng chúng đều nhanh như nhau. Chỉ cần cắt thêm '0' ở mỗi đầu của vectơ và nó hoàn hảo. –

Các vấn đề liên quan