0

我想更改某些参数的名称。

按照指南,我应该使用lifecycle::deprecate_warn旧名称,然后将其归属于新名称。

但是,在我的函数中,该参数通常与 quosures 一起使用,因此归因失败并出现错误:

library(tidyverse)
library(lifecycle)
library(rlang)
my_fun = function(df, cols, .vars = deprecated()){
  if (quo_is_missing(enquo(cols)) && !quo_is_missing(enquo(.vars))) {
    deprecate_warn("0.1.6", "my_fun(.vars=)", "my_fun(cols=)")
    cols <- .vars #error is thrown here
  }
  select(df, {{cols}})
}

my_fun(iris, cols=Sepal.Length) %>% head()
#>   Sepal.Length
#> 1          5.1
#> 2          4.9
#> 3          4.7
#> 4          4.6
#> 5          5.0
#> 6          5.4
my_fun(iris, .vars=Sepal.Length) %>% head()
#> Warning: The `.vars` argument of `my_fun()` is deprecated as of <NA> 0.1.6.
#> Please use the `cols` argument instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_warnings()` to see where this warning was generated.
#> Error in my_fun(iris, .vars = Sepal.Length): objet 'Sepal.Length' introuvable

reprex 包(v0.3.0)于 2021-01-28 创建

我盲目地尝试了各种东西,enquo但没有任何效果。

如何将旧名称归因于新名称?

4

1 回答 1

1

回想一下,这{{!!enquo(). 由于您想引用colsor .vars,这取决于缺少哪个,我建议单独执行!!and enquo()

my_fun = function(df, cols, .vars = deprecated()){
  if (quo_is_missing(enquo(cols)) && !quo_is_missing(enquo(.vars))) {
    deprecate_warn("0.1.6", "my_fun(.vars=)", "my_fun(cols=)")
    cols <- enquo(.vars)    # Quote .vars, if cols is missing
  }
  else cols <- enquo(cols)  # Quote cols, if cols is not missing

  select(df, !!cols)        # Unquote with !!, instead of {{, which is !!enquo()
}

my_fun(iris, cols=Sepal.Length) %>% head()    # Works
my_fun(iris, .vars=Sepal.Length) %>% head()   # Also works

如果您绝对必须使用{{,则修改捕获的表达式的唯一方法是更改​​函数的调用方式。这可以通过一点递归来完成(即,my_fun调用自身):

my_fun = function(df, cols, .vars = deprecated()){
  if (quo_is_missing(enquo(cols)) && !quo_is_missing(enquo(.vars))) {
    deprecate_warn("0.1.6", "my_fun(.vars=)", "my_fun(cols=)")
    return( my_fun(df, {{.vars}}) )   # .vars will be captured as cols
  }

  select(df, {{cols}})
}
于 2021-01-28T15:43:31.857 回答