如何在 R 函数中使用不同数量的默认值参数?

How to have varying number of arguments with default value in function in R?

我是 R 的新手,正在创建一个函数来突出显示图中数据集中的国家/地区列表。

功能问题如果国家名称没有作为参数传递(可能会有所不同),那么它应该能够从默认的国家列表中获取。

我知道 ... 用于 variable arguments 然后我可以使用 list(...) 但我无法将其与默认值放在一起。

有什么办法可以这样写:country_highlight_plot(Australia, Singapore, Norway) 如果我没有提到任何国家,那么它将采用默认国家。

代码如下(使用gapminder数据重现):

library(tidyverse)
library(gghighlight)
library(scales)
library(gapminder)

country_highlight_plot <- function(df = gapminder, y_var = gdpPercap, 
                                   background_line_color = "grey", 
                                   countries = default_list 
                                   ){
  
  # default list of highlight countries
  default_list = c("India","Singapore","Malaysia","Norway",
                                     "Denmark","United States","United Kingdom","China")
  
  # quoting y-axis variable
  y_var = enquo(y_var)

  # Data Prep.
  df %>% 
    mutate(highlight_type = case_when(country %in% countries ~ "Yes",
                                      TRUE ~ "No")) %>%
  # Plotting  
  ggplot() +
    geom_line(aes(x = year, y = round(!!y_var,2), col = country), size = 1.1) +
    
    gghighlight(highlight_type == "Yes",
                unhighlighted_params = list(size = 1, colour = alpha(background_line_color, 0.4))) +

    # facet_wrap(~continent) +
    
    theme_bw() +
    theme(axis.text.x = element_text(angle = 90)
            ) +
    
    labs(title = "GDP/Cap for world countries across time",
         subtitle = "created by ViSa",
         caption = "Data Source: Gapminder",
         y = "Total Tax Revenue % of GDP" 
         )
}

country_highlight_plot()

# EDITED below line to gapminder df only
# country_highlight_plot(df=gapminder, y_var=gdpPercap, background_line_color= "pink")

我认为设置合理的默认值并检查它对我来说很有意义。

我倾向于区分 NULLNA,其中 NULL 表示“不使用或全部使用”,而 NA 表示“使用合理的默认值” .

未测试:

country_highlight_plot <- function(df = gapminder, y_var = gdpPercap, 
                                   background_line_color = "grey", 
                                   countries = NA) {
  if (is.null(countries)) {
    countries <- sort(unique(df[["country"]])) # assuming 'country' is in there
  } else if (anyNA(countries)) {
    countries <- c("India", "Singapore", "Malaysia", "Norway",
                   "Denmark", "United States", "United Kingdom", "China")
    countries <- intersect(countries, unique(df[["country"]]))
  }
  # ...
}

这允许对 df 中的所有国家/地区使用 country_highlight_plot(..., countries=NULL),并为您的默认国家/地区列表使用 country_highlight_plot(..., countries=NA)intersect 调用确保如果此函数作为 filtered-gapminder 数据集的一部分被调用,它不会查找不存在的国家/地区。 (根据您当前的 %in% 用法,这可能不是绝对必要的......但如果您将 countries 用于任何其他用途,它可能仍然有用。防御性编程。)

切线:如果您将函数编写为包的一部分,那么我建议您应该导入(强制)gapminder 包,然后使用类似的技术来使用该数据集:

country_highlight_plot <- function(df, y_var = gdpPercap, 
                                   background_line_color = "grey", 
                                   countries = NA) {
  if (missing(df)) {
    df <- get("gapminder", envir = asNamespace("gapminder"))
  }
  if (is.null(countries)) {
    countries <- sort(unique(df[["country"]])) # assuming 'country' is in there
  } else if (anyNA(countries)) {
    countries <- c("India", "Singapore", "Malaysia", "Norway",
                   "Denmark", "United States", "United Kingdom", "China")
  }
  # ...
}

有了这个,你就可以做到

# default data, your default_list
country_highlight_plot()

# default data, all countries
country_highlight_plot(countries = NULL)

# pre-defined data, all default_list countries found
dplyr::filter(gapminder, ...) %>%
  country_highlight_plot(.)

# pre-defined data, all countries found
dplyr::filter(gapminder, ...) %>%
  country_highlight_plot(., countries = NULL)

# default data, manual countries
country_highlight_plot(countries = c("a","B"))