In R, evaluate expressions within vector of strings
Just apply the whole function.
sapply(foo, function(x) eval(parse(text=x)))
Evaluate expression given as a string
The eval()
function evaluates an expression, but "5+5"
is a string, not an expression. Use parse()
with text=<string>
to change the string into an expression:
> eval(parse(text="5+5"))
[1] 10
> class("5+5")
[1] "character"
> class(parse(text="5+5"))
[1] "expression"
Calling eval()
invokes many behaviours, some are not immediately obvious:
> class(eval(parse(text="5+5")))
[1] "numeric"
> class(eval(parse(text="gray")))
[1] "function"
> class(eval(parse(text="blue")))
Error in eval(expr, envir, enclos) : object 'blue' not found
See also tryCatch.
R: How to go from a vector of strings to a vector of quotes / names?
List apply as.symbol() to your input vector.
lapply(X = input, as.symbol)
How to correctly evaluate a literal character vector
You have to use get
to get an object with the given name.
eval(parse(text = get(paste0(question_stem, "_my_vector"))))
#[1] "Element 1" "Element 2" "Element 3" "Element 4
eval(parse(text=x)) inside a function, how to evaluate in global environment?
eval
has an argument, envir
, that allows you to specify the environment in which you want to evaluate your expression. So,
eval(parse(text=command[i]), envir=.GlobalEnv)
should hopefully work.
Evaluate an expression given as a string inside substitute()
parse()
returns an expression
, which is essentially a list of language objects marked as a different type. You want to put a language object into the title, so I think this is what you want:
plot(0~1, xlab = substitute("My"~ind, list(ind = parse(text = mystrng)[[1]])))
That gives this as the x label:
This won't work if mystrng
isn't legal R syntax, so "My index[1]"
will need some preprocessing to convert it to something legal like "My~index[1]"
R sometimes fails to evaluate expressions parsed from strings
The issue is that glm
stores the name of the variable used to reference the data, and stepAIC
then attempts to retrieve this name and evaluate it to access the data, but gets confused about which environment the variable was defined in. To demonstrate, I'm going to simplify your code to
mdl <- str2lang(modelfiller("y", 2, "x", "lag")) # This is your y~x+lag01+lag02
dfn <- df %>% tidyr::nest( data = c(-group) ) # First step of your %>% chain
glms <- purrr::map( dfn$data, ~glm(data = .x, mdl) ) # Construct the models
# Examine glms to observe that
# Call: glm(formula = mdl, data = .x) <--- glm() remembers that the data is in .x
# but stepAIC is not properly aware of where .x
# is defined and behaves effectively as
MASS::stepAIC( glms[[1]] ) # Error: object '.x' not found
Option 1
One workaround is to manually construct the expression that contains the data and then evaluate it:
glm2 <- function(.df, ...) {
eval(rlang::expr(glm(!!rlang::enexpr(.df),!!!list(...)))) }
glms2 <- purrr::map( dfn$data, ~glm2(data = .x, mdl) ) # Same as above, but with glm2
MASS::stepAIC( glms2[[1]] ) # Now works
Changing glm
to glm2
in your problematic spot makes your code work too. The down side is that the Call:
then remembers the entire data frame, which can be problematic if they are very large.
Option 2
Another alternative is to replace the purrr
call with a for
loop, which helps maintain the calling frames assumed by stepAIC
, thus guiding it to where the data is defined
# This fails with Error: object '.x' not found
purrr::map( dfn$data, ~MASS::stepAIC(glm(data=.x, mdl), direction="both") )
# This works
for( mydata in dfn$data )
MASS::stepAIC(glm(data=mydata, mdl), direction="both")
The advantage here is not needing to store the entire data frame inside the call. The disadvantage is that you effectively lose access to what purrr
does to streamline the code.
Evaluating mathematical expression in R
You can evaluate the string within your data.table 's environment. As a quick example:
#parse the text first
express <- parse(text = 'A+(B*C)/D')
#dummy data
library(data.table)
dt <- data.table(A = runif(5),
B = runif(5),
C = runif(5),
D = runif(5))
#using eval
eval(express, envir = dt)
#[1] 0.2654480 0.6818451 0.7611150 5.5714248 2.8076066
Related Topics
Shiny: How to Adjust the Width of the Tabsetpanel
Dynamically Add Function to R6 Class Instance
How to Plot the Relative Proportions of Two Groups Using a Fill Aesthetic in Ggplot2
R Xts: Generating 1 Minute Time Series from Second Events
Geom_Boxplot() from Ggplot2:Forcing an Empty Level to Appear
Change Internal Function of a Package
Geom_Line - Different Colour in the Same Line
Replace Missing Value with Previous Value
R-Shiny Using Reactive Renderui Value
Long and Wide Data - When to Use What