在x轴上以可变条宽度作为日期范围的条形图
我希望制作一个条形图,其中响应变量(重量变化)在不同长度的时间段内测量,由开始和结束日期定义。条的宽度应该与期间的长度相对应。我的数据的一个小例子:在x轴上以可变条宽度作为日期范围的条形图
wtchange.data <- structure(list(start.date = structure(1:3, .Label = c("2015-04-01",
"2015-04-15", "2015-04-30"), class = "factor"), end.date = structure(1:3, .Label = c("2015-04-15",
"2015-04-30", "2015-05-30"), class = "factor"), wtchange = c(5L,
10L, 15L), se = c(1.2, 2.5, 0.8)), .Names = c("start.date", "end.date",
"wtchange", "se"), class = "data.frame", row.names = c(NA, -3L
))
wtchange.data
# start.date end.date wtchange se
# 1 2015-04-01 2015-04-15 5 1.2
# 2 2015-04-15 2015-04-30 10 2.5
# 3 2015-04-30 2015-05-30 15 0.8
wtchange.data$start.date <- as.Date(wtchange.data$start.date)
wtchange.data$end.date <- as.Date(wtchange.data$end.date)
尝试使用geom_bar
:
library(ggplot2)
ggplot(wtchange.data, aes(x = start.date, y = wtchange)) +
geom_bar(stat = "identity", color = "black") +
geom_errorbar(aes(ymin = wtchange-se, ymax = wtchange+se), width = 1)
(不允许> 2间< 10声誉的联系,所以很遗憾不能显示第一图)
主要问题是,当定义绘图区美学(x = start.date, y = wtchange
)时,对于x轴,我只能使用一个变量(本例中为start.date),但我确实需要以某种方式使用start.date和end.date来限定对应于每个周期的条宽度。该图应该看起来像这样(在Paint中绘制):
第二个问题是条纹应该没有间隙地接触,但我不确定它是否可能,因为条纹必须是不同的宽度,所以你不能为所有酒吧设置一个酒吧宽度。是否可以手动设置每个条的宽度?
编辑: 谢谢Henrik的链接。我取得了一些进展。 余计算的日期中点在定心杆:
wtchange.data$date.midpoint <- wtchange.data$start.date +
(wtchange.data$end.date - wtchange.data$start.date)/2
然后计算周期长度为使用如棒宽度:
wtchange.data$period.length <- wtchange.data$end.date - wtchange.data$start.date
更新图形代码现在:
ggplot(wtchange.data, aes(x = date.midpoint, y = wtchange)) +
geom_bar(stat = "identity", color = "black", width = wtchange.data$period.length) +
geom_errorbar(aes(ymin = wtchange-se, ymax = wtchange+se), width = 1)
剩下的唯一问题是我在一个地方酒吧之间仍然存在一个小差距。我想这是由于R将日期差异计算到最近的天数的方式?
你是对的:它是计算结束和开始日期之间的差异,这是差距的原因。在计算宽度和中点时,我们需要使用numeric
周期而不是difftime
(请参阅下面的说明)。
# length of periods, width of bars as numeric
df$width <- as.numeric(df$end.date - df$start.date)
# mid-points
df$mid <- df$start.date + df$width/2
# dates for breaks
dates <- unique(c(df$start.date, df$end.date))
ggplot(df, aes(x = mid, y = wtchange)) +
geom_bar(stat = "identity", color = "black", width = df$width) +
geom_errorbar(aes(ymin = wtchange - se, ymax = wtchange + se), width = 1) +
scale_x_date(breaks = dates)
通讯geom_rect
代码:
# mid-points
df$mid <- df$start.date + as.numeric(df$end.date - df$start.date)/2
# dates for breaks
dates <- unique(c(df$start.date, df$end.date))
ggplot(df, aes(x = mid, y = wtchange)) +
geom_rect(aes(xmin = start.date, xmax = end.date, ymin = 0, ymax = wtchange), color = "black") +
geom_errorbar(aes(ymin = wtchange - se, ymax = wtchange + se), width = 1) +
scale_x_date(breaks = dates)
略少用油墨geom_step
苛刻:
# need to add an end date to the last period
df2 <- tail(df, 1)
df2$start.date <- df2$end.date
df2 <- rbind(df, df2)
# mid-points
df$mid <- df$start.date + as.numeric(df$end.date - df$start.date)/2
ggplot() +
geom_step(data = df2, aes(x = start.date, y = wtchange)) +
geom_errorbar(data = df, aes(x = mid, ymin = wtchange - se, ymax = wtchange + se), width = 1) +
scale_x_date(breaks = dates) +
ylim(0, 16) +
theme_bw()
在 “difftime
问题”:
Date
类的值可以在内部为小数天(见?Date
和?Ops.Date
来表示;尝试:Sys.Date()
; Sys.Date() + 0.5
; Sys.Date() + 0.5 + 0.5
)。但是,将difftime
对象添加到Date
时,difftime
对象是四舍五入的最接近的全天(请参阅?Ops.Date
中的x
参数)。
让我们来看看使用起始日期2015-04-15
和结束日期2015-04-30
计算:
mid <- (as.Date("2015-04-30") - as.Date("2015-04-15"))/2
mid
# Time difference of 7.5 days
str(mid)
# Class 'difftime' atomic [1:1] 7.5
# ..- attr(*, "units")= chr "days"
# calculate the midpoint using the difftime object
as.Date("2015-04-15") + mid
# [1] "2015-04-23"
# calculating midpoint using numeric object yields another date...
as.Date("2015-04-15") + as.numeric(mid)
# [1] "2015-04-22"
# But is "2015-04-15" above in fact fractional, i.e. "2015-04-22 point 5"?
# Let's try and add 0.5
as.Date("2015-04-15") + as.numeric(mid) + 0.5
# [1] "2015-04-23"
# Yes.
因此,我们使用numeric
时期,而不是difftime
时期。