Help with non-standard evaluation


#1

Suppose I have the following data frame

library(tidyverse)
index <- 1:1000
df1 <- data.frame(index = glue::glue('index[{index}]'),
                  X = rnorm(1000))

I would like to write a function that takes a data frame, the name of a variable of that data frame, and returns a new data frame like the following

df2 <- df1 %>% mutate(index = as.numeric(gsub("index\\[(\\d+)\\]", "\\1", index)))

where, in this case the name of the variable is index.

I tried this:

myFunc <- function(data, name){
  name <- enquo(name)
  df1 <- data %>% mutate(!!name := as.numeric(gsub("index\\[(\\d+)\\]", "\\1", !!name)))
  return(df1)
}

test <- myFunc(data = df1, name=index)

Alas, I get this error:

 Error: The LHS of `:=` must be a string or a symbol 

What am I doing wrong?

Thanks!


#2

The variable name on the left-hand side of := should be a string. You can use quo_name() for this.

You can put this in mutate() in your function.

mutate(!!quo_name(name) := as.numeric(gsub("index\\[(\\d+)\\]", "\\1", !!name)))

#3

Thanks! There is only one more thing that i need to change and is not working. gsub("index\ instead of index it should be name. I tried glue but i'm messing something up:

myFunc <- function(data, name){
  name <- enquo(name)
  df1 <- data %>% mutate(!!quo_name(name) := as.numeric(gsub(glue::glue('{name}\\[(\\d+)\\]'), "\\1", !!name)))
  return(df1)
}

I also tried to add !! before name but that did not help :frowning:


#4

This did the trick for me:

myFunc <- function(data, name){
  name <- enquo(name)
  df1 <- data %>% mutate(!!quo_name(name) := as.numeric(gsub(glue::glue('{rlang::quo_text(name)}\\[(\\d+)\\]'), "\\1", !!name)))
  return(df1)
}