John P. S.
John P. S.

Reputation: 383

Tidy Evaluation not working with mutate and stringr

I've trying to use Tidy Eval and Stringr togheter inside a mutate pipe, but every time I run it it gives me an undesirable result. Instead of changing the letter 'a' for the letter 'X', it overwrite the entire vector with the column name, as you can see in the example below, that uses the IRIS dataset.

text_col="Species"
iris %>% 
  mutate({{text_col}} := str_replace_all({{text_col}}, pattern = "a", replacement = "X"))

result:

    structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6, 5, 5.4, 4.6, 
5, 4.4, 4.9, 5.4, 4.8, 4.8, 4.3, 5.8), Sepal.Width = c(3.5, 3, 
3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3, 3, 4), Petal.Length = c(1.4, 
1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 1.4, 1.1, 
1.2), Petal.Width = c(0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 
0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2), Species = c("Species", "Species", 
"Species", "Species", "Species", "Species", "Species", "Species", 
"Species", "Species", "Species", "Species", "Species", "Species", 
"Species")), row.names = c(NA, 15L), class = "data.frame")

Doesn't Stringr supports tidy evaluation or the curly-curly ({{}}) operator??

Upvotes: 0

Views: 192

Answers (1)

Ronak Shah
Ronak Shah

Reputation: 388907

Tidy evaluation completely depends on how you send your inputs.

For example, if you send your input as an unquoted variable your attempt would work.

library(dplyr)
library(stringr)
library(rlang)

change_fun <- function(df, text_col) {
  df %>%  mutate({{text_col}} := str_replace_all({{text_col}}, "a","X"))
}

change_fun(iris, Species) %>% head

#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1          5.1         3.5          1.4         0.2  setosX
#2          4.9         3.0          1.4         0.2  setosX
#3          4.7         3.2          1.3         0.2  setosX
#4          4.6         3.1          1.5         0.2  setosX
#5          5.0         3.6          1.4         0.2  setosX
#6          5.4         3.9          1.7         0.4  setosX

To pass input as quoted variables use sym to convert into symbol first and then evaluate !!.

change_fun <- function(df, text_col) {
   df %>%  mutate(!!text_col := str_replace_all(!!sym(text_col), "a","X"))
}

change_fun(iris, "Species") %>% head

#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1          5.1         3.5          1.4         0.2  setosX
#2          4.9         3.0          1.4         0.2  setosX
#3          4.7         3.2          1.3         0.2  setosX
#4          4.6         3.1          1.5         0.2  setosX
#5          5.0         3.6          1.4         0.2  setosX
#6          5.4         3.9          1.7         0.4  setosX

Upvotes: 3

Related Questions