Nick Larsen Nick Larsen - 1 month ago 10
R Question

Apply holiday labels to plot by week of year

I have some holiday dates, and a bunch of data by week of year. I'm plotting the data and want to make the X axis labels only show up when there is a holiday from my holidays table. The rest of the labels should be hidden. I think what I need is a list where the names are the weeks of year and the values are the strings I want, but I can't figure out how to generate that programatically.

library(tidyverse)
library(lubridate)

holiday_dates = c(
"2016-01-01",
'2016-01-18',
'2016-02-15',
'2016-05-08',
'2016-05-30',
'2016-06-19',
'2016-07-04',
'2016-09-16',
'2016-10-10',
'2016-11-11',
'2016-11-24',
'2016-12-25'
)
holiday_names = c(
'New Years Day',
'Martin Luther King Day',
'Presidents Day',
'Mothers Day',
'Memorial Day',
'Fathers Day',
'Independence Day',
'Labor Day',
'Columbus Day',
'Veterans Day',
'Thanksgiving',
'Christmas Day'
)
holidays = data.frame(Date = as.Date(holiday_dates), Holiday = holiday_names) %>%
mutate(WeekOfYear = week(Date))

# can't figure out how to make this a list with names generates from the WeekOfYear column
holiday_labels = data.frame(WeekOfYear = seq(1,52)) %>%
left_join(holidays) %>%
.$Holiday

my_data %>%
ggplot(aes(x=WeekOfYear, y=Gross, group=WeekOfYear)) +
geom_line() +
scale_x_discrete(
names = holiday_labels,
na.value = ""
)

Answer
  • Use scale_x_continuous rather than scale_x_discrete
  • Set both labels and breaks, with the corresponding text labels and the dates where you want them. In particular, for breaks use week(as.Date(holiday_dates)) to put it on the same scale as your data.

For example:

For example:

data_frame(WeekOfYear = 1:52, Gross = rnorm(52)) %>%
  ggplot(aes(x = WeekOfYear, y = Gross)) +
  geom_line() +
  scale_x_continuous(
    labels = holiday_names,
    breaks = week(as.Date(holiday_dates))
  ) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Note that I also rotated the x-axis labels to make it readable.

Comments