Mario
Mario

Reputation: 573

dplyr inconsistent behaviour inside function

This problem happens when instead of using the dplyr::mutate function on its own, I insert it in a function, it doesnt work! Look:

library(tidyverse)
data1<-data.frame(a=c(1:2), x1=c(2:3))

fun <- function(df1, coldf1){
  df1 %>% mutate(coldf1 = 1) %>% return()
}

fun(data1, "a")
data1 %>% mutate("a" = 1)

The two codes are identical but the results are unexpected like so:

> fun(data1, "a")
  a x1 coldf1
1 1  2      1
2 2  3      1
> data1 %>% mutate("a" = 1)
  a x1
1 1  2

I know something is up with the assignment with the equality, and the same problem happened in the left_join function too. Is there a universal solution for these things?

Upvotes: 0

Views: 32

Answers (1)

r2evans
r2evans

Reputation: 160407

You can't do that with dplyr, which is heavily into "non-standard evaluation" (NSE). Inside your function, dplyr sees coldf1 = 1 and assigns a new column, just like you can do df1 %>% mutate(somethingnew = 3.1415).

You need to use either rlang's escaping mechanisms (with :=) ...

fun <- function(df1, coldf1) {
  df1 %>% mutate(!!coldf1 := 1)
}

data1
#   a x1
# 1 1  2
# 2 2  3
fun(data1, "a")
#   a x1
# 1 1  2
# 2 1  3

or basic R :

fun <- function(df1, coldf1) { df1[[coldf1]] <- 1; df1; }
fun(data1, "a")
#   a x1
# 1 1  2
# 2 1  3

(though I'm assuming your example is simplified, where this might not be as simple)

Regardless, look into "programming with dplyr", https://dplyr.tidyverse.org/articles/programming.html.

Upvotes: 1

Related Questions