You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决sugrrants::facet_calendar日期换行问题及替代方案

使用sugrrants::facet_calendar生成日历图的换行问题及解决方法

问题描述

使用sugrrants::facet_calendar生成日历图时,若月份需要超过默认的5行7列布局,月末日期会被换行到日历顶部(例如2025年3月的30日、31日),期望这些日期能显示在第6行。

可复现代码

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)

调整参数时的错误

尝试通过facet_calendar的nrow/ncol参数修改行数时,设置非默认的NULL值会触发如下错误:

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.
Run `rlang::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

自定义解决方案

改用ggh4x::facet_manual并编写自定义函数生成布局,解决日期换行问题。替换后的facet代码行如下:

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用于区分当前日期日历和过往月份日历。

以下是生成facet_manual布局字符串的自定义函数,供参考:

get_facet_manual_design <- function(input_date) {
  
  # 获取当月第一天
  first_this_month <- make_datetime(year(input_date), month(input_date), 1)
  
  # 计算月初需要的占位#数量(根据第一天的星期数)
  hashs_needed_start <- wday(first_this_month) - 1
  
  # 计算月末需要的占位#数量
  hashs_needed_end <- 7 - wday(input_date)
  
  # 计算当月需要的符号数量(对应天数)
  symbols_needed <- as.numeric(input_date - as.Date(first_this_month)) + 1
  
  # 符号库,用于对应每日的facet
  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")
  
  ##### 生成布局字符串
  # 初始化月初占位#
  design <- rep("#", hashs_needed_start)
  
  # 添加对应天数的符号
  design <- design |> 
    append(head(symbolbank, symbols_needed))
  
  # 添加月末占位#
  design <- design |> 
    append(rep("#", hashs_needed_end))
  
  # 计算需要插入的换行符数量
  number_newlines <- floor(length(design) / 7) - 1
  newlines <- c("")
  newlines <- append(newlines, rep("\n", number_newlines))
  
  # 插入换行符并整理成矩阵
  design <- rbind(newlines, matrix(design, ncol = length(newlines)))
  
  # 合并为最终布局字符串
  design <- design |> paste(collapse = "")
  this_months_design <- str_glue(design)
  
  return(this_months_design)
  
}

内容的提问来源于stack exchange,提问作者banjaloupe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 03:22:02