Search code examples
rdplyrtidyeval

Using tidy evaluation function inside mutate without explicit reference to original dataframe


I'd like to create a function that works inside of mutate. As a simple example, I can get this to work:

library(tidyverse)

# Toy Data
df <- tibble::tribble(
  ~id, ~first_name, ~gender, ~height,
  1,   "john",      "m",     71,
  2,   "jane",      "f",     64,
  3,   "sally",     "f",     65
)

double_it <- function(df, x) {
  x <- enquo(x)
  pull(df, !!x) * 2
}

df %>% mutate(height_2 = double_it(., height))

# A tibble: 3 x 5
     id first_name gender height height_2
  <dbl> <chr>      <chr>   <dbl>    <dbl>
1     1 john       m          71      142
2     2 jane       f          64      128
3     3 sally      f          65      130

But, what I'd like to get to is this:

double_it <- function(x) {
  ???
}

df1 %>% mutate(height_2 = double_it(height))

# A tibble: 3 x 5
     id first_name gender height height_2
  <dbl> <chr>      <chr>   <dbl>    <dbl>
1     1 john       m          71      142
2     2 jane       f          64      128
3     3 sally      f          65      130

Solution

  • You could use .data$ as prefix:

    library(tidyverse)
    
    # Toy Data
    df1 <- tibble::tribble(
      ~id, ~first_name, ~gender, ~height,
      1,   "john",      "m",     71,
      2,   "jane",      "f",     64,
      3,   "sally",     "f",     65
    )
    
    double_it <- function(x) {
      x * 2
    }
    
    df1 %>% mutate(height_2 = double_it(.data$height))
    #> # A tibble: 3 x 5
    #>      id first_name gender height height_2
    #>   <dbl> <chr>      <chr>   <dbl>    <dbl>
    #> 1     1 john       m          71      142
    #> 2     2 jane       f          64      128
    #> 3     3 sally      f          65      130
    

    or just use height directly:

    double_it <- function(x) {
      x * 2
    }
    
    df1 %>% mutate(height_2 = double_it(height))
    #> # A tibble: 3 x 5
    #>      id first_name gender height height_2
    #>   <dbl> <chr>      <chr>   <dbl>    <dbl>
    #> 1     1 john       m          71      142
    #> 2     2 jane       f          64      128
    #> 3     3 sally      f          65      130