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

Posted

技术标签:

【中文标题】如何在R中的函数中有不同数量的具有默认值的参数?【英文标题】:How to have varying number of arguments with default value in function in R? 【发布时间】:2020-10-14 15:47:14 【问题描述】:

我是 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")

【问题讨论】:

dots &lt;- list(...); if (!length(dots)) dots &lt;- default_list; tax_rev 未定义 @Peter tax_rev 是另一个数据框,我认为它仅用于注释代码,因为它也可以在其他数据框上工作,并且可以通过提及参数 df = gapminder, y_var = gdpPercap.. 等来更改。但我会在原始帖子中编辑和更新到 gapminder。 【参考方案1】:

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

我倾向于区分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"]]))
  
  # ...

这允许您使用country_highlight_plot(..., countries=NULL) 表示df 中的所有国家/地区,并使用country_highlight_plot(..., countries=NA) 作为您的默认国家/地区列表。 intersect 调用确保如果此函数作为过滤后的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"))

【讨论】:

感谢@r2evans 提供详细的解释和代码。在这里发布问题之前,我已经尝试过country_highlight_plot(countries = c("Australia","Singapore")),但我认为这不是一个聪明和好的方法。感谢您列出所有选项!

以上是关于如何在R中的函数中有不同数量的具有默认值的参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在R中的一列中添加具有不同值的新行

如何在java中动态实例化具有不同数量参数的java类?

R语言 直方图

R进阶:缺失值的处理、拟合关系

如何在 jdbcTemplate 中为具有相同值的多个参数标记传递参数?

InjectMocks 不适用于具有默认值的 Kotlin 构造函数参数