如何在 R ggplot 图的函数中包含查找表和/或将某些字符串传递到图中?

How to include a lookup table in a function for R ggplot graph and/or pass certain strings into graph?

提问人:abby23 提问时间:11/15/2023 最后编辑:abby23 更新时间:11/15/2023 访问量:46

问:

我正在尝试在 R 中编写一个函数来重新创建 ggplot 图。该图表使用气候数据,我希望能够轻松地针对 3 种不同的气候情景(rcp 列)和多个不同的百分位数/平滑度重新制作它。

用于生成示例数据帧的代码:

df_hist <- data.frame(rcp = c("Hist", "Hist", "Hist", "Hist", "Hist", "Hist"), 
    date = c(1979, 1980, 1981, 1982, 1983, 1984), mean = c(97.1124289537908, 
        135.364260728983, 24.4033167950203, 153.59677124136, 
        177.594607139079, 39.6085327444814), Q05 = c(4.1381868023812e-65, 
        2.94270229560265e-68, 3.86129081174159e-81, 1.06605479821109e-51, 
        1.79404728324904e-40, 8.28390180526523e-36), Q25 = c(1.01269396115261e-41, 
        8.78115797693937e-45, 3.82879556669681e-37, 2.60884128233389e-28, 
        4.39037901508925e-17, 7.68605084861368e-15), median = c(1.85605943345325e-12, 
        1.95575826419004e-15, 1.14253007463387e-13, 7.23576991419774e-05, 
        0.140429987721102, 7.63006636355939e-06), Q75 = c(21.4021262157246, 
        31.3895154168531, 0.0333018038213947, 96.3254717677912, 
        274.5007935262, 1.60034420671794), Q95 = c(615.545600520142, 
        660.3338816459, 199.63296816906, 847.03945259953, 797.645790902726, 
        250.623552018151))

这是我的工作功能。它采用上面的数据帧。但是,它还没有根据我的喜好进行定制。现在,ylow 和 yhigh 的默认值是 Q05 和 Q95,它们与我输入的用于手动缩放颜色的文本(“第 5 个百分位数”和“第 95 个百分位数”)相匹配。我希望有某种方法可以让这个函数可以检测为 ylow 和 yhigh 设置的百分位数,然后相应地更改文本。例如,如果 ylow 设置为 Q25,则会将“第 5 个百分位数”更改为“第 25 个百分位数”。我在想潜在的某种查找表,但无法弄清楚如何实现这一点。

graph_timeseries_quantile <- function(ts_list,
                                      ylow = Q05,
                                      yhigh = Q95,
                                      hist_rcp_name = "Hist",
                                      xaxis = date, 
                                      ysmooth = mean) {
  df_hist %>% ggplot(aes(x={{xaxis}}, y = {{ysmooth}})) +
    geom_line(aes(y={{ylow}}, color="5th Percentile", lty="5th Percentile"), lwd=1) +
    geom_line(aes(y={{yhigh}}, color="95th Percentile", lty="95th Percentile"), lwd=1) +
    geom_ribbon(aes(x={{xaxis}}, ymin = {{ylow}}, ymax = {{yhigh}}), fill = "#E0EEEE", alpha = 0.5) +
    geom_smooth(method = "loess", se=F, col="gray")+
    geom_line(aes(color = "Annual Mean Historical", lty = "Annual Mean Historical"), lwd=1) +
    # RCP lines and ribbon
    theme_bw() +
    scale_color_manual(name = "Legend", 
                       values = c("5th Percentile" = "dodgerblue4", 
                                  "95th Percentile" = "aquamarine",
                                  "Annual Mean Historical" = "black")) +
    scale_linetype_manual(name = "Legend",
                          values = c("5th Percentile" = 3,
                                     "95th Percentile" = 3,
                                     "Annual Mean Historical" = 1)) + 
    labs(x="Year", y="Annual Flow (cfs)", title=paste0("Annual Historical Streamflow"))
}

graph_timeseries_quantile(df_hist)

上图结果

我的另一个想法是手动将文本输入到函数中,但是当我尝试这样做时,它只是将那行关闭。请参阅下面的示例,其中我向函数“ychar_low”添加了一个参数,并将其设置为“第 5 个百分位数”,它删除了底线:

graph_timeseries_quantile <- function(ts_list,
                                      ylow = Q05,
                                      ychar_low = "5th Percentile",
                                      yhigh = Q95,
                                      hist_rcp_name = "Hist",
                                      xaxis = date, 
                                      ysmooth = mean) {
  df_hist %>% ggplot(aes(x={{xaxis}}, y = {{ysmooth}})) +
    geom_line(aes(y={{ylow}}, color=ychar_low, lty=ychar_low), lwd=1) +
    geom_line(aes(y={{yhigh}}, color="95th Percentile", lty="95th Percentile"), lwd=1) +
    geom_ribbon(aes(x={{xaxis}}, ymin = {{ylow}}, ymax = {{yhigh}}), fill = "#E0EEEE", alpha = 0.5) +
    geom_smooth(method = "loess", se=F, col="gray")+
    geom_line(aes(color = "Annual Mean Historical", lty = "Annual Mean Historical"), lwd=1) +
    # RCP lines and ribbon
    theme_bw() +
    scale_color_manual(name = "Legend", 
                       values = c(ychar_low = "dodgerblue4", 
                                  "95th Percentile" = "aquamarine",
                                  "Annual Mean Historical" = "black")) +
    scale_linetype_manual(name = "Legend",
                          values = c(ychar_low = 3,
                                     "95th Percentile" = 3,
                                     "Annual Mean Historical" = 1)) + 
    labs(x="Year", y="Annual Flow (cfs)", title=paste0("Annual Historical Streamflow"))
}
graph_timeseries_quantile(df_hist)

添加参数ychar_low后的图形

任何建议将不胜感激。这是我第一次尝试使用带有 ggplot 图的函数。

R 函数 ggplot2 查找 tidyeval

评论


答:

2赞 stefan 11/15/2023 #1

一种方法是使用 将不带引号的列名转换为字符串,然后使用 例如 或。。。以分配标签。在下面的代码中,我使用命名向量作为标签以及颜色和线型的向量。rlang::as_labelswitch

注意。我还用于颠倒图例中项目的顺序。limits=rev

library(ggplot2)

graph_timeseries_quantile <- function(ts_list,
                                      ylow = Q05,
                                      yhigh = Q95,
                                      hist_rcp_name = "Hist",
                                      xaxis = date,
                                      ysmooth = mean) {
  get_label <- function(x) {
    x <- rlang::as_label(x)
    switch(x,
      "Q05" = "5th Percentile",
      "Q25" = "25th Percentile",
      "Q75" = "75th Percentile",
      "Q95" = "95th Percentile",
      "unknown Percentile"
    )
    # Alternative:
    # paste0(
    #   readr::parse_number(x),
    #   "th Percentile"
    # )
  }

  labels <- c(
    ylow = get_label(enquo(ylow)),
    yhigh = get_label(enquo(yhigh)),
    mean = "Annual Mean Historical"
  )

  pal_color <- c(
    ylow = "dodgerblue4",
    yhigh = "aquamarine",
    mean = "black"
  )

  pal_lty <- c(
    ylow = 3,
    yhigh = 3,
    mean = 1
  )

  df_hist |>
    ggplot(aes(x = {{ xaxis }}, y = {{ ysmooth }})) +
    geom_line(aes(y = {{ ylow }}, color = "ylow", lty = "ylow"), lwd = 1) +
    geom_line(aes(y = {{ yhigh }}, color = "yhigh", lty = "yhigh"), lwd = 1) +
    geom_ribbon(aes(x = {{ xaxis }}, ymin = {{ ylow }}, ymax = {{ yhigh }}),
      fill = "#E0EEEE", alpha = 0.5
    ) +
    geom_smooth(method = "loess", se = F, col = "gray") +
    geom_line(aes(color = "mean", lty = "mean"), lwd = 1) +
    # RCP lines and ribbon
    theme_bw() +
    scale_color_manual(
      name = "Legend",
      limits = rev,
      labels = labels,
      values = pal_color
    ) +
    scale_linetype_manual(
      name = "Legend",
      limits = rev,
      labels = labels,
      values = pal_lty
    ) +
    labs(
      x = "Year", y = "Annual Flow (cfs)",
      title = paste0("Annual Historical Streamflow")
    )
}

graph_timeseries_quantile(df_hist)
#> `geom_smooth()` using formula = 'y ~ x'


graph_timeseries_quantile(df_hist, Q25, Q75)
#> `geom_smooth()` using formula = 'y ~ x'

评论

0赞 abby23 11/15/2023
太棒了,非常感谢!!这给了我很多话要说。我从未在 R 中的另一个函数中使用过一个函数,而且我以前也从未使用过这个函数——所以这个评论教会了我很多。我认为这将解决我的问题!switch()