Home > Back-end >  How to eval(parse(text= var_name), envir= df) if var_name is a number?
How to eval(parse(text= var_name), envir= df) if var_name is a number?

Time:03-29

Using eval I make different stuff with variables. Here is an example where simply the variable a is returned without any transformations:

df <- data.frame(1:10); var_name <- "a"
names(df) <- var_name
eval(parse(text= var_name), envir= df) 
[1]  1  2  3  4  5  6  7  8  9 10

This works as expected. But if I call a column name as a number, e.g. 3, this does not return the expected vector 1:10:

df <- data.frame(1:10); var_name <- "3"
names(df) <- var_name
eval(parse(text= var_name), envir= df)
[1] 3

I understand that in first example I get the expected output because eval(...) is same as saving a as a variable in the global environment and then calling it, i.e. a <- df$a; a. On the other hand, the second example is same as typing 3 which returns [1] 3. Is there a way to make clear that even with numbers we want eval(...) to look for variable names in the envir argument?

All I've come up with is eval(parse(text= "`3`"), envir= df) but I need a solution where I can provide the variable name with the vector var_name.

CodePudding user response:

There are a couple of options here. You could wrap var_name in as.symbol

df <- data.frame(1:10); var_name <- "3"
names(df) <- var_name
eval(as.symbol(var_name), envir = df)
#> [1]  1  2  3  4  5  6  7  8  9 10

Or, possibly simpler, you could use get instead:

df <- data.frame(1:10); var_name <- "3"
names(df) <- var_name
get(var_name, envir = as.environment(df))
#> [1]  1  2  3  4  5  6  7  8  9 10

Note though that passing strings around as objects to be parsed into code is generally bad practice, whether you use get or eval - see here for a few reasons why.

  • Related