我正在测量某些工作站中一集的持续时间。我有一集的开头和剧集结束的时间戳。我想想出一个图,其中y轴是一天中的时间,而x轴是观察日。任何想法我怎么能做到这一点?
例如我有
id start end
1 01/01/2010 10:00:00 02/01/2010 22:00:00
1 04/01/2012 08:00:00 04/01/2012 14:00:00
我想构建一个像附件
的情节
我有什么想法可以做到这一点?与附图不同,我希望在图中具有精确的准确性/表示。
非常感谢
答案 0 :(得分:4)
首先,您的示例数据不可重现;我假设日期是日/月/年,但显示的很难说。此外,日期类型在R
中是特定的,因此了解您拥有的类型非常重要。首先,我将创建一个类似的可重现数据集:
DF <-
structure(list(id = c(1L, 1L), start = structure(c(1262340000,
1262592000), class = c("POSIXct", "POSIXt"), tzone = "GMT"),
end = structure(c(1262469600, 1262613600), class = c("POSIXct",
"POSIXt"), tzone = "GMT")), .Names = c("id", "start", "end"
), row.names = c(NA, -2L), class = "data.frame")
看起来像
> DF
id start end
1 1 2010-01-01 10:00:00 2010-01-02 22:00:00
2 1 2010-01-04 08:00:00 2010-01-04 14:00:00
现在,为了绘制这个,我们需要做几个转换。必须将日期和时间分开,因为它们被绘制在不同的轴上。
library("chron")
library("plyr")
DF$start.day <- as.Date(DF$start)
DF$end.day <- as.Date(DF$end)
DF$start.time <- as.chron(DF$start) - floor(as.chron(DF$start))
DF$end.time <- as.chron(DF$end) - floor(as.chron(DF$end))
此外,必须将日期转换为已过去的日期。
t0 <- min(DF$start.day, DF$end.day)-1
DF$start.monitored.day <- as.numeric(DF$start.day - t0)
DF$end.monitored.day <- as.numeric(DF$end.day - t0)
最后,跨越午夜的时段必须分成多个范围,以便每个范围包含在给定的一天内。这一步不是很简单。
DF$index <- seq_len(nrow(DF))
DF <- ddply(DF, .(index), function(df) {
if(df$start.monitored.day == df$end.monitored.day) {
df
} else {
data.frame(start.monitored.day = df$start.monitored.day : df$end.monitored.day,
end.monitored.day = df$start.monitored.day : df$end.monitored.day,
start.time = c(df$start.time, rep(times("00:00:00"), df$end.monitored.day-df$start.monitored.day)),
end.time = times(c(rep(times("23:59:59"), df$end.monitored.day-df$start.monitored.day), df$end.time)),
id = df$id,
index = df$index)
}
})
现在数据采用可以绘制的格式。
> DF[c("start.monitored.day", "end.monitored.day", "start.time", "end.time")]
start.monitored.day end.monitored.day start.time end.time
1 1 1 10:00:00 23:59:59
2 2 2 00:00:00 22:00:00
3 4 4 08:00:00 14:00:00
我将使用ggplot
来绘制它,因为我对它更熟悉,因为我做了一些previous work on time scales with it。
从该博客文章中提取
library("ggplot2")
library("scales")
timesreverse_trans <- function() {
trans <- function(x) {-as.numeric(x)}
inv <- function(x) {times(-x)}
fmt <- function(x) {
notone <- x != 1
simplify <- !any(diff(x) < 1/(24*60))
ifelse(notone,
format(x-floor(x), simplify=simplify),
ifelse(simplify, "24:00", "24:00:00"))
}
trans_new("chrontimes-reverse",
transform = trans,
inverse = inv,
breaks = pretty_breaks(),
format = fmt,
domain=c(0,1))
}
scale_y_times <- function(..., trans=NULL) {
scale_y_continuous(..., trans=timesreverse_trans())
}
刚刚离开实际情节
ggplot(DF) +
geom_rect(aes(xmin = start.monitored.day - 0.5,
xmax = start.monitored.day + 0.5,
ymin = start.time,
ymax = end.time)) +
scale_y_times("Time") +
scale_x_continuous("Monitored day")