5

I have a much more complicated function but the minimal version of it boils down to the following where I need to convert the entered function by the user to a character. But I can't figure out how to do this (I've also tried a bunch of rlang hacks that didn't work).

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'

How can I do this?

Indrajeet Patil
  • 4,673
  • 2
  • 20
  • 51

3 Answers3

4

maybe this would work?

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

so using your function:

> 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"
user1317221_G
  • 15,087
  • 3
  • 52
  • 78
4

You can use identical to compare the argument .f with the function you are interested in:

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"

The issue with the original approach is that as.character(sum) or any type of as.character(fx) does not mean anything to R. You can use substitute(.f) == quote(stats::lm) as well. Mainly, we need to intercept .f before it is evaluated and returns a function.

Cole
  • 11,130
  • 1
  • 9
  • 24
1

Here's another dplyr option using enquo and 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"
Matt
  • 7,255
  • 2
  • 12
  • 34