Как построить гистограмму месячных отклонений от среднегодового значения?
ТАК!
Я пытаюсь создать график месячных отклонений от среднегодовых значений температуры с помощью гистограммы. У меня есть данные за многие годы, и я хочу показать сезонное поведение температур между месяцами. Столбцы должны представлять отклонение от среднегодового значения, которое пересчитывается для каждого года. Вот пример, который похож на то, что я хочу, только на один год:
Мои данные конфиденциальны, поэтому я пока не могу ими поделиться, но я сделал воспроизводимый пример, используя набор данных 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