I'm having some trouble creating a calendar using sugrrants::facet_calendar that does not wrap dates from the end of the month to the top of the calendar, when the month would have more than 5 rows. The default behavior is to create a calendar with 5 rows and 7 columns. Here's some example code that creates a working facet_calendar:
library(hms)
library(sugrrants)
library(tidyverse)
tribble(~date_time, ~count,
"2025-03-01 10:00 AM", 10,
"2025-03-01 11:00 AM", 8,
"2025-03-01 12:00 PM", 6,
"2025-03-10 10:00 AM", 3,
"2025-03-10 11:00 AM", 4,
"2025-03-10 12:00 PM", 5,
"2025-03-12 10:00 AM", 7,
"2025-03-12 11:00 AM", 9,
"2025-03-12 12:00 PM", 11,) |>
mutate(date_time = parse_date_time(date_time, orders = "ymd HM p")) |>
mutate(date = as.Date(date_time)) |>
mutate(time = as_hms(date_time)) |>
ggplot(aes(x = time)) +
geom_line(aes(y = count)) +
facet_calendar(~ date, week_start = 7)
The output preview is attached.
In the preview, March 30 & 31st are wrapped to the top of the calendar, and I'd rather have them in a 6th row instead.
There are nrow and ncol parameters that are supposed to change the number of rows, however setting them to anything besides the default of NULL gives me this error:
Error in dplyr::tibble()
:
! Tibble columns must have compatible sizes.
- Size 31: Existing data.
- Size 186: Column
MROW
. i Only values of size one are recycled. Runrlang::last_trace()
to see where the error occurred. Warning message: In row_idx[] <- map2(.x = row_idx, .y = n_idx, function(.x, .y) .x + : number of items to replace is not a multiple of replacement length
Is this something I can fix in my example dataset, another thing I can change with facet_calendar, or another calendar data view option I should be using instead? Thank you!
EDIT: I wanted to follow up since there hadn't been any solutions for this, I ended up switching to use ggh4x::facet_manual
and wrote up a function to create the design given an input date. So, rather than facet_calendar
, I now have this line:
facet_manual(~ date, design = if_else(today() > last_day_of_month, get_facet_manual_design(last_day_of_month), get_facet_manual_design(today())))
last_day_of_month
is defined earlier on, and lets me distinguish between a calendar for today's date, versus one for a previous month.
Here's the function to get the facet_manual
design string, in case that helps someone else in a similar situation who finds this later:
get_facet_manual_design <- function(input_date) {
# get the first of the month
first_this_month <- make_datetime(year(input_date), month(input_date), 1)
# figure out which wday the first of the month is
# to get how many leading #s will be needed
# by subtracting the wday number from 7
hashs_needed_start <- wday(first_this_month) - 1
# similarly get the hashes needed after the end
hashs_needed_end <- 7 - wday(input_date)
# get the number of days between now and the first of the month
# this will tell us how many letters to generate
symbols_needed <- as.numeric(input_date - as.Date(first_this_month)) + 1
# letter string to pull from
symbolbank <- c("1", "2", "3", "4", "5", "6", "7",
"8", "9", "A", "B", "C", "D", "E",
"F", "G", "H", "I", "J", "K", "L",
"M", "N", "O", "P", "Q", "R", "S",
"T", "U", "V", "W", "X", "Y", "Z")
##### MAKING DESIGN STRING
# create the #s at the start
design <- rep("#", hashs_needed_start)
# create the letters
design <- design |>
append(head(symbolbank, symbols_needed))
# create the #s needed at the end
design <- design |>
append(rep("#", hashs_needed_end))
# figure out how many rows (aka \n's) to add
number_newlines <- floor(length(design) / 7) - 1
newlines <- c("")
newlines <- append(newlines, rep("\n", number_newlines))
# insert the /n symbols
design <- rbind(newlines, matrix(design, ncol = length(newlines)))
# collapse into a string
design <- design |> paste(collapse = "")
this_months_design <- str_glue(design)
return(this_months_design)
}