假设我们有一个超过2年的时间表。每年,我们都想在特定的日子做一些事情,并在时间线上标记这些日子。类似于Gant char,但不同之处在于句点之间可以有间隙。这意味着,例如,4月13日到20日有一个活动,同年5月1日到8日有下一个活动。在下面的MWE中,我仅使用从2000年1月1日到28日的时间段。2000年2月,为了简单起见:
library(data.table)
library(ggplot2)
x <- seq(as.Date("2000/01/01"),
as.Date("2000/02/28"), "day")
y <- x
y[c(3,6,8,9,34:43,50:59)] <- NA
x[c(1,2,3,12:33,44:58)] <- NA
timetable <- data.table(Year=c(rep("Year_1",59),rep("Year_2",59)),
date=c(x,y))我如何创建一个以矩形形式说明活动的时间表?与此处显示的图表类似:Gantt charts with R或此处:Creating a Multi-Project Timeline Using ggplot2 in R,但此处应允许两者之间的间隙。
所以换句话说,我想做的就是填写一个现有的时间表,并留下没有活动的日子(空白)。如何使用ggplot2实现这一点
发布于 2019-10-17 15:36:55
因此,这是一种可能性;您首先找出哪些日期缺少值,然后运行长度编码缺少值:
is_missing <- timetable[, rle(is.na(date)), by = Year]由此,您可以很容易地计算表中不缺少的日期的位置:
end <- cumsum(is_missing$lengths)
start <- end - is_missing$lengths + 1
# Take now only the parts that are not missing
end <- end[!is_missing$values]
start <- start[!is_missing$values]在此基础上,您可以构建包含期间开始日期和结束日期的新数据帧:
newdf <- data.frame(
Year = timetable$Year[start],
start = timetable$date[start],
end = timetable$date[end]
)
newdf$y <- 1:nrow(newdf) # just a counter for visualisation您可以使用它来绘制如下所示的内容:
ggplot(newdf) +
geom_rect(aes(xmin = start, xmax = end,
ymin = 0 + y,
ymax = 1 + y, fill = Year))

请注意,Year变量实际上并不表示年份,因为日期本身只跨越一年(2000年),所以我将其视为分类变量。此外,newdf中的第3个和第6个条目只有一天,在绘图中显示为一个宽度为零的矩形,因为它在同一点开始和结束:
> newdf
Year start end y
1 Year_1 2000-01-04 2000-01-11 1
2 Year_1 2000-02-03 2000-02-12 2
3 Year_1 2000-02-28 2000-02-28 3
4 Year_2 2000-01-01 2000-01-02 4
5 Year_2 2000-01-04 2000-01-05 5
6 Year_2 2000-01-07 2000-01-07 6
7 Year_2 2000-01-10 2000-02-02 7
8 Year_2 2000-02-13 2000-02-18 8如果您想要显示这1天的时间段,可以在aes()函数中执行xmax = end + 1或xmin = start - 1。
编辑:对于y轴上的Year变量,您可以在geom_rect()中将其视为数字
ggplot(newdf) +
geom_rect(aes(xmin = start, xmax = end,
ymin = -0.45 + as.numeric(Year),
ymax = 0.45 + as.numeric(Year), fill = Year)) +
scale_y_continuous(breaks = seq_len(nlevels(newdf$Year)),
labels = levels(newdf$Year))

https://stackoverflow.com/questions/58421693
复制相似问题