此代码:
library(lubridate)
library(ggplot2)
library(scales)
.months <- 3
.minor.intervals <- 4
.minor.intervals.num <- .months * .minor.intervals
sdate <- as.POSIXct("2015-01-01")
edate <- sdate + months(.months)
df <- data.frame(x = seq(from = sdate, to = edate,
length.out = .minor.intervals.num * 2),
y = 1:(.minor.intervals.num * 2))
p <- ggplot(df, aes(x = x, y = y))
xbm <- seq(from = sdate, to = edate, length.out = .minor.intervals.num)
p <- p + scale_x_datetime(limits = c(sdate, edate),
breaks = date_breaks("month"),
minor_breaks = xbm)
p <- p + geom_line() + geom_point()
plot(p)
给我错误:Error in Ops.POSIXt((x - from[1]), diff(from)) : '/' not defined for "POSIXt" objects
如果我评论minor_breaks
部分 - 一切正常。
如果我将minor_breaks
部分更改为minor_breaks = date_breaks("week")
- 一切都有效。
但是我想将4个月分成4个部分......
如何解决?
答案 0 :(得分:2)
我找到了解决问题的方法,但我必须承认,我不确定为什么必须这样做。似乎minor_breaks
期望数值而不是日期作为输入。
我使用以下代码创建了中断:
maj.breaks <- sdate + months(0:.months)
min.breaks <- do.call(c,
lapply(1:.months,function(m) {
seq(maj.breaks[m],maj.breaks[m+1],length.out = .minor.intervals+1)
})
)
依赖于示例中定义的变量。请注意与定义次要中断的方式的不同之处:由于每个月的长度不同,仅将开始日期和结束日期之间的范围简单分割为适当数量的段是不够的。你必须自己每个月分开。
如上所述,您必须先将min.breaks
转换为数字,然后再将其传递给minor_breaks
。我按如下方式制作情节:
p <- ggplot(df, aes(x = x, y = y)) +
scale_x_datetime(limits = c(sdate, edate),
breaks = maj.breaks,
minor_breaks = as.numeric(min.breaks)) +
geom_line() + geom_point()
plot(p)
这与您的代码相同,直至breaks
和minor_breaks
的输入。因为您的版本也可以使用,所以无需使用向量maj.breaks
。但我认为值得注意的是,breaks
适用于类POSIXct
的输入,而minor_breaks
需要数值。不幸的是,我不知道原因。