ggplot2:yearmon scale和geom_bar

时间:2017-05-18 07:36:40

标签: r ggplot2 xts

除了解决方案之外,我还想了解为什么某些内容应该非常简单,实际上并非如此。

[我正在从一个涉及该问题的不同帖子中借用部分代码,但最终找到了我不喜欢的解决方案]

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()

第一个情节是错的;第二个几乎是完美的(X轴上的刻度不是很好,但我可以忍受)。 Isn&#t; t geom_bar()应该执行我必须在第二张图表中手动执行的计数工作吗?

第一个图表 poor plot

第二个图表 better plot

我的问题是:为什么第一张图表如此差劲?有一个警告意味着建议一些东西(&#34; position_stack需要非重叠的x区间&#34;)但我真的不理解它。 感谢。

我的个人答案

这就是我所学到的(非常感谢大家!):

  • 即使有scale_#_yearmonscale_#_date,遗憾的是 ggplot 会将这些对象类型视为连续数字。这使geom_bar无法使用。
  • geom_histogram可能会做到这一点。但你失去了对aestethics相关部分的控制。
  • 底线:您需要在图表
  • 之前进行分组/求和
  • 不确定(如果您打算使用ggplot2) xts lubridate 对我想要实现的目标非常有用。我怀疑任何连续的案例 - 日期 - 他们将是完美的。

全押,我结束了这完全符合我的目标(注意不需要 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"))

最终输出 final plot

2 个答案:

答案 0 :(得分:1)

第一个图被拧紧的原因基本上是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

因此,当您在没有先前聚合的情况下进行绘图时,条形图会展开。您需要使用binwidth分配适当的geom_histogram(),如下所示:

ggplot(tmp, aes(x = yearmon, fill = status)) + 
  geom_histogram(binwidth = 1/12) + 
  scale_x_yearmon()

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)))

答案 1 :(得分:0)

您也可以aes(x=factor(yearmon), ...)作为快捷方式修复。