Как построить гистограмму месячных отклонений от среднегодового значения?

ТАК!

Я пытаюсь создать график месячных отклонений от среднегодовых значений температуры с помощью гистограммы. У меня есть данные за многие годы, и я хочу показать сезонное поведение температур между месяцами. Столбцы должны представлять отклонение от среднегодового значения, которое пересчитывается для каждого года. Вот пример, который похож на то, что я хочу, только на один год:

Аляска Температура

Мои данные конфиденциальны, поэтому я пока не могу ими поделиться, но я сделал воспроизводимый пример, используя набор данных 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 выше или ниже. Вы все классные, и я бы приветствовал ЛЮБОЙ совет!!!!

2 ответа

Решение

Вероятно, главная проблема здесь в том, что geom_col() не будет принимать другие эстетические свойства, если вы явно не скажете это. Один из способов получить то, что вы хотите, это использовать два вызова geom_col() создать две разные гистограммы, которые будут объединены в два разных слоя. Кроме того, вам нужно будет создать информацию о дате, которую можно легко передать ggplot(); Я использую lubridate() пакет для этой задачи.

Обратите внимание, что мы объединяем столбцы "месяц" и "год" здесь, а затем используемymd() получить значения даты. Я решил не преобразовывать столбец с датой "двойного значения" в txhousing используя что-то вроде date_decimal()потому что иногда это может сбить с толку февральские и январские месяцы (например, 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

Участок:

введите описание изображения здесь

Вы можете увидеть периодическое поведение здесь хорошо; Увеличение продаж, по-видимому, происходит каждую весну, а продажи падают в осенние и зимние месяцы. Имейте в виду, что вы можете изменить цвета, которые я назначил, если вы хотите использовать этот код для температурных данных! Это было весело - удачи и счастливого заговора!

Как то так должно работать?

По сути, вам нужно создать двоичную переменную, которая позволит вам изменить цвет (fill) если salesdiff является положительным или отрицательным, называется ниже factordiff,

Плюс тебе нужен был date переменная для month а также year вместе взятые.

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

Другие вопросы по тегам