Search code examples
rtidyversetidyevalnon-standard-evaluation

How to use tidyeval in base function in r


I wrote a function. In my function, there is a step that needs to extract the number of non-repeating values, similar to this:

df = data.frame(a = c(1, 1:3))
df

length(unique(df$a))

> length(unique(df$a))
[1] 3

I use tidyeval for programming, which means that the user does not need to use quotation marks when entering parameters.

I tried many ways, but they all failed.

None of the following codes will work.

my_fun1 <- function(data, var){
  l = length(unique(data${{var}}))
  l
}

my_fun2 <- function(data, var){
  l = data %>% {length(.${{var}})}
  l
}

my_fun3 <- function(data, var){
  l = with(data, length(unique({{var}})))
  l
}
my_fun1(df, a)
my_fun2(df, a)
my_fun3(df, a)

Solution

  • Here are a couple of options. If you're committed to base R type functions, you could use:

    library(dplyr)
    df = data.frame(a = c(1, 1:3))
    
    my_fun1 <- function(data, var){
      tmp <- data[[quo_name(enquo(var))]]
      length(unique(tmp))
    }
    my_fun1(df, a)
    #> [1] 3
    

    Alternatively, if you would rather do this in the tidy framework, you could do the following:

    my_fun2 <- function(data, var){
      data %>% select({{var}}) %>% distinct() %>% nrow()
    }
    my_fun2(df, a)
    #> [1] 3
    

    Created on 2022-07-10 by the reprex package (v2.0.1)