r - 创建有间隙的时间线
问题描述
假设我们有一个超过 2 年的时间表。每年,我们都想在特定的日子做一些事情,并在时间轴上标记这些日子。类似于 Gant char,但不同之处在于句点之间可以有间隔。这意味着例如从 13. 到 20. 4 月有一个活动,下一个活动从 1. 到 8. 同年 5 月。在下面的 MWE 中,为简单起见,我仅使用从 2000 年 1 月 1 日到 2000 年 2 月 28 日的时间段:
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))
如何创建以矩形形式说明活动的时间表?与此处显示的图表类似: 带有 R 的甘特图 或此处: 在 R 中使用 ggplot2 创建多项目时间线 但此处应该允许两者之间存在间隙。
所以换句话说,我要做的是填写现有的时间表,并省略没有活动的日子(空白)。如何做到这一点ggplot2
?
解决方案
所以这是一种可能性;您首先找出哪些日期是缺失值,然后运行长度对缺失进行编码:
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 年),因此我将其视为分类变量。此外,第 3 和第 6 个条目newdf
只有一天,在图中显示为零宽度矩形,因为它在同一点开始和结束:
> 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 天的时间段出现,您可以在函数内部执行xmax = end + 1
或操作。xmin = start - 1
aes()
编辑:对于Year
y 轴上的变量,您可以将它们视为数字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))
推荐阅读
- java - 在 Postman 的请求正文中传递多个 JSON 数据并使用 Jersy(JXRS) 进入 Java Rest API
- c# - 发布。NET 核心 Web 应用程序。在window和linux中
- php - php中的在线考试时间倒计时
- firebase - 获取firebase函数实例ID?
- xaml - Xamarin.Forms:如何在样式中设置“GestureRecognizers”
- jquery - 隐藏前一个表并在 jQuery 中单击时显示新表
- angular - 如何在点击时在 PrimeNg 的 p 日历中打开特定的年份和月份
- html - 使用 sed 删除 html 表格列
- javascript - 将 NodeJS MySql 与 React 应用程序集成
- docker - thajeztah/pgadmin4 到本地安装的 postgresql