不仅仅是一个解决方案,我想了解为什么应该很容易的事情,实际上并非如此。
[我从另一篇触及该问题的帖子中借用了部分代码,但最终得到了一个我不喜欢的解决方案]
library(ggplot2)
library(xts)
library(dplyr)
library(scales)
csvData <- "dt,status
2015-12-03,1
2015-12-05,1
2015-12-05,0
2015-11-24,1
2015-10-17,0
2015-12-18,0
2016-06-30,0
2016-05-21,1
2016-03-31,0
2015-12-31,0"
tmp <- read.csv(textConnection(csvData))
tmp$dt <- as.Date(tmp$dt)
tmp$yearmon <- as.yearmon(tmp$dt)
tmp$status <- as.factor(tmp$status)
### Not good. Why?
ggplot(tmp, aes(x = yearmon, fill = status)) +
geom_bar() +
scale_x_yearmon()
### Almost good but long-winded and ticks not great
chartData <- tmp %>%
group_by(yearmon, status) %>%
summarise(count = n()) %>%
as.data.frame()
ggplot(chartData, aes(x = yearmon, y = count, fill = status)) +
geom_col() +
scale_x_yearmon()
Run Code Online (Sandbox Code Playgroud)
第一个情节全错了;第二个几乎是完美的(X 轴上的刻度不是很好,但我可以接受)。不geom_bar()应该执行我必须在第二个图表中手动执行的计数工作吗?
我的问题是:为什么第一个图表如此糟糕?有一个警告是为了提出一些建议(“position_stack 需要不重叠的 x 间隔”),但我真的无法理解。谢谢。
我的个人回答
这就是我学到的(非常感谢你们所有人!):
scale_#_yearmonor scale_#_date,不幸的是ggplot将这些对象类型视为连续数字。这使得geom_bar无法使用。geom_histogram可能会起作用。但是你失去了对美学相关部分的控制。总而言之,我以这个完美地完成了我所追求的(请注意如何不需要xts或lubridate):
library(ggplot2)
library(dplyr)
library(scales)
csvData <- "dt,status
2015-12-03,1
2015-12-05,1
2015-12-05,0
2015-11-24,1
2015-10-17,0
2015-12-18,0
2016-06-30,0
2016-05-21,1
2016-03-31,0
2015-12-31,0"
tmp <- read.csv(textConnection(csvData))
tmp$dt <- as.Date(tmp$dt)
tmp$yearmon <- as.Date(format(tmp$dt, "%Y-%m-01"))
tmp$status <- as.factor(tmp$status)
### GOOD
chartData <- tmp %>%
group_by(yearmon, status) %>%
summarise(count = n()) %>%
as.data.frame()
ggplot(chartData, aes(x = yearmon, y = count, fill = status)) +
geom_col() +
scale_x_date(labels = date_format("%h-%y"),
breaks = seq(from = min(chartData$yearmon),
to = max(chartData$yearmon), by = "month"))
Run Code Online (Sandbox Code Playgroud)
第一个情节被搞砸的原因基本上ggplot2并不完全是这样yearmon。正如你在这里看到的,它只是一个num带有标签的内部。
> as.numeric(tmp$yearmon)
[1] 2015.917 2015.917 2015.917 2015.833 2015.750 2015.917 2016.417 2016.333 2016.167 2015.917
Run Code Online (Sandbox Code Playgroud)
因此,当您在没有之前聚合的情况下进行绘图时,条形图会展开。您需要像这样分配适当的binwidth使用:geom_histogram()
ggplot(tmp, aes(x = yearmon, fill = status)) +
geom_histogram(binwidth = 1/12) +
scale_x_yearmon()
Run Code Online (Sandbox Code Playgroud)
1/12对应每年12个月。
对于聚合后的绘图,正如 @ed_sans 所建议的,我也更喜欢lubridate,因为我更了解如何更改刻度和修改轴标签。
chartData <- tmp %>%
mutate(ym = floor_date(dt,"month")) %>%
group_by(ym, status) %>%
summarise(count = n()) %>%
as.data.frame()
ggplot(chartData, aes(x = ym, y = count, fill = status)) +
geom_col() +
scale_x_date(labels = date_format("%Y-%m"),
breaks = as.Date("2015-09-01") +
months(seq(0, 10, by = 2)))
Run Code Online (Sandbox Code Playgroud)