首页 > 解决方案 > ggplot2 使用 facetscales 包更改每个单独的 facet 面板的日期轴限制

问题描述

我想知道是否有人可以帮助我应用该facetscales包为每个方面创建不同的日期范围。scales = "free_x"我知道在调用中可以实现类似的东西ggplot,但我希望用它来以编程方式确定每个方面的规模应该扩大的天数。

我在这里看到了一个相关问题的回答(请参阅 Uwe 的回答),但我无法让代码正确评估日期。

我在下面提供了一个简短的数据示例。根据 Uwe 对问题的回答,我期望 ggplot ggproto 对象的列表可以作为列表包含在绘图函数中,但是,代码似乎无法正确评估日期。

非常感谢任何帮助。

df <- structure(list(zone = c("zone1", "zone1", "zone1", "zone1", "zone1", 
                                                            "zone1", "zone1", "zone1", "zone1", "zone1", "zone2", "zone2", 
                                                            "zone2", "zone2", "zone2", "zone2", "zone2", "zone2", "zone2", 
                                                            "zone2"), date = structure(c(16294, 16295, 16296, 16297, 16298, 
                                                                                                                     16299, 16300, 16301, 16302, 16303, 16304, 16305, 16306, 16307, 
                                                                                                                     16308, 16309, 16310, 16311, 16312, 16313), class = "Date"), Q = c(317, 
                                                                                                                                                                                                                                                        299, 290, 276, 277, 238, 239, 266, 278, 278, 93, 102, 107, 124, 
                                                                                                                                                                                                                                                        122, 110, 93, 89, 85, 92)), class = c("grouped_df", "tbl_df", 
                                                                                                                                                                                                                                                                                                                                    "tbl", "data.frame"), row.names = c(NA, -20L), groups = structure(list(
                                                                                                                                                                                                                                                                                                                                        zone = c("zone1", "zone2"), .rows = list(1:10, 11:20)), row.names = c(NA, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    -2L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))


facet_params <- df %>% 
    group_by(zone) %>%
    summarise(start_date=min(date, na.rm=TRUE), end_date=max(date, na.rm=TRUE)) %>%
    mutate(duration = end_date-start_date, 
                 extra_days = trunc(as.integer(duration)*.3),
                 breaks=c(2,4))

scales_y <- facet_params %>% 
    str_glue_data(
        "`{zone}` = scale_x_date(limits = c({as.Date(start_date)}, {as.Date(end_date)}), ", 
        "breaks = seq({as.Date(start_date)}, {as.Date(end_date)}, {breaks}))") %>%
    str_flatten(", ") %>% 
    str_c("list(", ., ")") %>% 
    parse(text = .) %>% 
    eval()

标签: rggplot2

解决方案


我不是语言计算方面的专家,但正如你所提到的,日期并没有被评估为正确的日期。错误消息似乎表明日期被解释为数学表达式2014 - 8 - 12(= 1994)。为了解决这个问题,我将as.Date()函数移到括号外,并在括号周围加上单引号。现在,日期被评估为"2014-8-12"可以as.Date()视为正确日期的日期。我也替换seq()seq.Date(),但我不知道这是否绝对必要。下面的代码对我有用:

scales_x <- facet_params %>% 
  str_glue_data(
    "`{zone}` = scale_x_date(limits = c(as.Date('{start_date}'), as.Date('{end_date}')), ", 
    "breaks = seq.Date(as.Date('{start_date}'), as.Date('{end_date}'), {breaks}))"
  ) %>%
  str_flatten(", ") %>% 
  str_c("list(", ., ")") %>% 
  parse(text = .) %>% 
  eval()

library(facetscales)

ggplot(df, aes(date, Q)) +
  geom_line() +
  facet_grid_sc(~ zone, scales = list(x = scales_x))

推荐阅读