【问题标题】:How to plot bar chart of monthly deviations from annual mean?如何绘制与年平均值的月度偏差的条形图?
【发布时间】:2019-04-16 03:19:18
【问题描述】:

所以!

我正在尝试使用条形图创建温度数据与年度平均值的月度偏差图。我有多年的数据,我想显示几个月之间温度的季节性行为。条形应代表与每年重新计算的年平均值的偏差。这是一个与我想要的类似的例子,只是它是一年的:

我的数据很敏感,所以我还不能分享它,但我使用 txhousing 数据集(它与 ggplot2 一起提供)做了一个可重现的示例。 salesdiff 列是月销售额(所有城市的平均值)与每年的年平均值之间的偏差。现在的问题是绘制它。

library(ggplot2)
df <- aggregate(sales~month+year,txhousing,mean)

df2 <- aggregate(sales~year,txhousing,mean)

df2$sales2 <- df2$sales #RENAME sales
df2 <- df2[,-2] #REMOVE sales

df3<-merge(df,df2) #MERGE dataframes

df3$salesdiff <- df3$sales - df3$sales2 #FIND deviation between monthly and annual means

#plot deviations
ggplot(df3,aes(x=month,y=salesdiff)) +
         geom_col()

我的 ggplot 目前看起来不太好-

它以某种方式将每个月的列与多年来的所有数据堆叠在一起。理想情况下,日期将沿着 x 轴跨越多年(我认为数据集是从 2000 年到 2015 年......),并且不同的颜色取决于 salesdiff 是更高还是更低。你们都很棒,我欢迎任何建议!!!!

【问题讨论】:

  • 创建一个Date 变量:df3$date &lt;- as.Date(paste(df3$year, df3$month, "01", sep = "-")),然后检查scale_x_date 的中断和格式。使用fill = salesdiff &gt; 0

标签: r ggplot2 plot mean periodicity


【解决方案1】:

这里的主要问题可能是geom_col() 不会具有不同的美学属性,除非您明确告诉它这样做。获得所需内容的一种方法是使用两次对geom_col() 的调用来创建两个不同的条形图,这些条形图将在两个不同的层中组合在一起。此外,您将需要创建可以轻松传递给ggplot() 的日期信息;我使用 lubridate() 包来完成这项任务。

注意我们这里将“月”和“年”列合并,然后使用ymd()获取日期值。我选择不使用 date_decimal() 之类的东西来转换 txhousing 中的双值“日期”列,因为有时它会混淆 2 月和 1 月的月份(例如,2 月 1 日“四舍五入”到 1 月 31 日)。

我决定绘制txhousing 数据集的一个子集,以方便教学。

代码:

library("tidyverse")
library("ggplot2")

# subset txhousing to just years >= 2011, and calculate nested means and dates
housing_df <- filter(txhousing, year >= 2011) %>%
  group_by(year, month) %>%
  summarise(monthly_mean = mean(sales, na.rm = TRUE),
            date = first(date)) %>%
  mutate(yearmon = paste(year, month, sep = "-"),
         date = ymd(yearmon, truncated = 1), # create date column
         salesdiff = monthly_mean - mean(monthly_mean), # monthly deviation
         higherlower = case_when(salesdiff >= 0 ~ "higher", # for fill aes later
                                 salesdiff < 0 ~ "lower"))

ggplot(data = housing_df, aes(x = date, y = salesdiff, fill = as.factor(higherlower))) +
  geom_col() +
  scale_x_date(date_breaks = "6 months",
               date_labels = "%b-%Y") +
  scale_fill_manual(values = c("higher" = "blue", "lower" = "red")) +
  theme_bw()+
  theme(legend.position = "none") # remove legend

剧情:

您可以在这里很好地看到周期性行为;每年春季的销售额似乎都会增加,而秋季和冬季月份的销售额会下降。请记住,如果您想将此代码用于温度数据,您可能需要反转我分配的颜色!这是一个有趣的 - 祝你好运,快乐的阴谋!

【讨论】:

  • 谢谢!!这是完美的!
【解决方案2】:

这样的东西应该可行吗?

基本上,您需要创建一个二进制变量,如果salesdiff 是正数或负数,您可以更改颜色 (fill),在下面调用factordiff

另外,您还需要一个 date 变量来组合 monthyear

library(ggplot2)
library(dplyr)

df3$factordiff <- ifelse(df3$salesdiff>0, 1, 0) # factor variable for colors

df3 <- df3 %>% 
  mutate(date = paste0(year,"-", month), # this builds date like "2001-1"
         date = format(date, format="%Y-%m")) # here we create the correct date format

#plot deviations
ggplot(df3,aes(x=date,y=salesdiff, fill = as.factor(factordiff))) +
  geom_col()

当然,这会导致情节难以阅读,因为您有很多日期,您可以对其进行子集化并仅显示有限的时间:

df3 %>% 
  filter(date >= "2014-1") %>% # we filter our data from 2014
  ggplot(aes(x=date,y=salesdiff, fill = as.factor(factordiff))) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) # adds label rotation

【讨论】:

    猜你喜欢
    • 2015-03-04
    • 2022-12-11
    • 2020-01-11
    • 2020-09-26
    • 1970-01-01
    • 2019-07-28
    • 2020-05-02
    • 2015-08-29
    • 2018-03-08
    相关资源
    最近更新 更多