首页 > 解决方案 > 当我对数据进行子集化时,为什么 ggplot 会忽略我的因子水平?

问题描述

我正在使用从上一个问题的答案中获得的一些代码,但我遇到了一个有趣的问题,我希望专家能深入了解正在发生的事情。我正在尝试使用条形图绘制与年度平均值的月度偏差。具体来说,我根据月平均值是高于还是低于年平均值来为不同的条形着色。我正在使用包txhousing中包含的数据集ggplot2

我想我可以用一个因素来表示是否是这种情况。当我只绘制数据的一个子集(“较低”值,但是当我添加另一个图时,将ggplot所有月份重新排列为按字母顺序排列。有谁知道为什么会发生这种情况,以及解决方法是什么? ?

非常感谢您的任何意见!欢迎批评我的代码:)

可重现的例子

1. 只使用一个情节

library(tidyverse)

# subset txhousing to just years >= 2011, and calculate nested means and dates
housing_df <- filter(txhousing, year == 2014) %>%
  group_by(year, month) %>%
  summarise(monthly_mean = mean(sales, na.rm = TRUE),
            date = first(date)) %>%
  mutate(month = factor(month.abb[month], levels = month.abb, ordered = TRUE),
         salesdiff = monthly_mean - mean(monthly_mean), # monthly deviation
         higherlower = case_when(salesdiff >= 0 ~ "higher",                                   
                                 salesdiff < 0 ~ "lower"))

ggplot(data = housing_df, aes(x = month, y = salesdiff, higherlower)) +
  geom_col(data = filter(housing_df, higherlower == "higher"), aes(y = salesdiff, fill = higherlower)) +
  scale_fill_manual(values = c("higher" = "blue", "lower" = "red")) +
  theme_bw() +
  theme(legend.position = "none") # remove legend

在此处输入图像描述

2. 使用包含所有数据的两个图:

ggplot(data = housing_df, aes(x = month, y = salesdiff, higherlower)) +
  geom_col(data = filter(housing_df, higherlower == "higher"), aes(y = salesdiff, fill = higherlower)) +
  geom_col(data = filter(housing_df, higherlower == "lower"), aes(y = salesdiff, fill = higherlower)) +
  scale_fill_manual(values = c("higher" = "blue", "lower" = "red")) +
  theme_bw() +
  theme(legend.position = "none") # remove legend

在此处输入图像描述

标签: rggplot2bar-chart

解决方案


有多种方法可以做到这一点,但我觉得它有点成功和尝试。您已经在进行最常见的修复,即将月份转换为因子,这就是第一个情节有效的原因。为什么它在第二种情况下不起作用有点神秘,但尝试添加+ scale_x_discrete(limits= housing_df$month)以覆盖 x 轴顺序,看看是否有效。

我同意其他评论,即最好的方法是甚至不使用额外的层,因为在这种特定情况下不需要它,但即使有多个层,上述解决方案也有效。


推荐阅读