6

这是我在使用...参数并tidyselect选择变量的包中的函数的简化版本:

# this toy function just selects the ... variables
foo <- function(dat = mtcars, ...){
  expr <- rlang::expr(c(...))
  cols_to_select <- tidyselect::eval_select(expr, data = dat)
  dplyr::select(dat, all_of(cols_to_select))
}

这有效:foo(mtcars, cyl)

但是我的实际函数在参数之前有更多前面的...参数,所有参数都具有默认值。在我使用这些默认值调用我的函数并将值传递给....

这就是我想要的 - 假设dat = mtcars- 但它不起作用:

foo(... = cyl)

错误:名称不得采用...或形式..j

我可以修改函数或调用以允许直接指定...吗?

4

1 回答 1

6

在点之后放置具有默认值的参数通常是一个好主意:

f <- function( ..., dat=mtcars )
    dplyr::select( dat, ... )

f(cyl)                 # Works
f(dat=iris, Species)   # Also works

如果您的 API 不允许您在点之后放置命名的默认参数,这里有另一种选择。请注意,您不必明确指定具有默认值的命名参数。您可以简单地让它们“丢失”:

foo(, cyl)    # Same as foo( dat=mtcars, cyl )

如果你有很多默认参数,并且你不想在你的调用中一直放一堆逗号,你可以利用purrr::partial()将这个模式捕获到一个独立的函数中:

foo2 <- purrr::partial(foo, ,)  # Effectively partial(foo, dat=mtcars)
foo2(cyl)                       # Works

如果这仍然涉及键入比您喜欢的更多的逗号,您可以再添加一个步骤:

foo3 <- purrr::partial( foo, !!!purrr::keep(formals(foo), nzchar) )
foo3(cyl, mpg)                  # Also works
于 2020-03-20T19:56:30.893 回答