5

我有一个更复杂的函数,但它的最小版本归结为以下,我需要将用户输入的函数转换为字符。但我无法弄清楚如何做到这一点(我也尝试了一堆rlang不起作用的黑客)。

foo <- function(.f) {
  if (as.character(.f) == "stats::lm") {
    print("this is lm")
  } else {
    print("this is not lm")
  }
}

foo(stats::lm)
#> Error in as.character(.f): cannot coerce type 'closure' to vector of type 'character'

我怎样才能做到这一点?

4

3 回答 3

4

也许这会起作用?

    deparse(substitute(stats::lm))
[1] "stats::lm"

所以使用你的功能:

> foo <- function(.f) {
+   if (deparse(substitute(.f)) == "stats::lm") {
+     print("this is lm")
+   } else {
+     print("this is not lm")
+   }
+ }
> 
> foo(stats::lm)
[1] "this is lm"
于 2020-07-15T11:12:35.887 回答
4

您可以使用identical将参数.f与您感兴趣的函数进行比较:

foo <- function(.f) {
    if (identical(.f, stats::lm)) {
        print("this is lm")
    } else {
        print("this is not lm")
    }
}

foo(stats::lm)
#> [1] "this is lm"

原始方法的问题是,as.character(sum)或任何类型as.character(fx)对 R 没有任何意义。您也可以使用substitute(.f) == quote(stats::lm)。主要是,我们需要.f在它被评估并返回一个函数之前进行拦截。

于 2020-07-15T11:19:46.927 回答
1

这是另一个dplyr使用enquoand的选项as_label

foo <- function(.f) {
.f <- enquo(.f)
  if (!!as_label(.f) == "stats::lm") {
    print("this is lm")
  } else {
    print("this is not lm")
  }
}

> foo(stats::lm)
[1] "this is lm"
于 2020-07-15T11:28:26.357 回答