取决于默认参数的函数参数

时间:2019-02-18 21:48:54

标签: r function parameter-passing

我正在尝试编写一个函数,该函数在R中具有默认参数。最后一个参数告诉我用户如何希望计算变量'g'。默认值为“ s + a”(前两个参数的总和),但原则上可以由任何函数指定(例如“ s-a”或“ s * a” ...)。

myFunc <- function(n, 
                   s = rbernoulli(n, p = 0.5), 
                   a = rnorm(n,sd = 2),2),
                   g = s + a){
      data.frame(s = factor(s),
                 a = a,
                 g = as.numeric(g>0))
}

如果我调用函数本身,这会很好:

myFunc(5)

要指定“ g”的计算方式,我想这样做:

myFunc(n = 5, g = a - s) (I)

myFunc(n = 5, a = ., s = ., g = a - s) (II)

似乎(I)会使R在工作空间中查找变量s / a,这不是我想要的。 (II)不存在,但这是我说“使用默认计算”的方式。

我尝试用NULL指定我的函数,但是那也不起作用。请注意,在获得值之后,我希望能够在函数中使用“ g”(例如,我不能用函数代替它)。

3 个答案:

答案 0 :(得分:3)

问题是g是在调用环境中评估的,而不是在myFunc内的环境中评估的。您可以添加一个参数,该参数指定要在其中评估g的环境,并使用默认值environment(),以便它默认为myFunc2内的环境。

myFunc2 <- function(n, 
                   s = rbernoulli(n, p = 0.5), 
                   a = rnorm(n,sd = 2),
                   g,
                   envir = environment()) {
      g <- if (missing(g)) s + a else eval(substitute(g), envir)
      data.frame(s = factor(s),
                 a = a,
                 g = as.numeric(g>0))
}
myFunc2(n = 5, g = s + a)

答案 1 :(得分:2)

我认为最好的方法是使g一个接受两个参数sa的函数。然后,您可以在需要时传递其他功能:

myFunc <- function(n,
                   s = purrr::rbernoulli(n, p = 0.5),
                   a = rnorm(n, sd = 2),
                   g = function(s, a) { s + a }) {
    g_val = g(s, a)
    data.frame(s = factor(s),
               a = a,
               g = as.numeric(g_val > 0))
}

myFunc(5)
myFunc(5, g = function(s, a) { s - a })

答案 2 :(得分:2)

这可以使用非标准评估来完成。有多种方法可以实现此目的。我现在主要使用quasure和rlang::eval_tidy。这是使用此功能的实现:

library(purrr)
library(rlang)
myFunc <- function(
  n, 
  s = rbernoulli(n, p = 0.5), 
  a = rnorm(n, sd = 2),
  g = s + a) {
  if (!missing(g)) {
    g <- eval_tidy(enquo(g), list(s = s, a = a))
  }
  data.frame(s = factor(s),
             a = a,
             g = as.numeric(g>0))
}

这将使用您建议的示例myFunc(n = 5, g = a - s)起作用。如果未提供g参数,则默认使用标准r功能,即在其他参数的上下文中评估默认表达式。

请注意,这也可以使用准引号,因此您可以执行以下操作:

my_expr <- expr(a - s)
myFunc(n = 5, g = !!my_expr)

couple of中有一个great chapters Hadley Wickham's Advanced R关于非标准评估。

仅使用基数R(您提供的purrrr:bernoulli除外):

library(purrr)
myFunc <- function(
  n, 
  s = rbernoulli(n, p = 0.5), 
  a = rnorm(n, sd = 2),
  g = s + a) {
  if (!missing(g)) {
    g <- eval(substitute(g), list(s = s, a = a))
  }
  data.frame(s = factor(s),
             a = a,
             g = as.numeric(g>0))
}