I'm trying to build a shiny app to help with a decision analysis. In part of the app, the user is required to enter their utility function as text, which R/shiny will convert to an expression. Suppose the user has three parts to their utility functions which will be combined into a larger utility function. The problem I have is defining the list elements in a for
loop:
utility.fns <- list()
ufs <- list() ## user input
## each ufs is specified by the user
ufs[[1]] <- "x+1"
ufs[[2]] <- "sin(x)"
ufs[[3]] <- "cos(x)^2"
for(i in 1:3){
## turn the text into functions
utility.fns[[i]] <- function(x){
eval( parse(text = ufs[[i]]) )
}
}
utility.fns[[1]](1) ## returns cos(1)^2 ?
The weird thing is that the list utility.fns
always returns utility.fns[[3]]
, regardless of the index. However, manually overriding
> utility.fns[[1]] <- function(x){
+ eval( parse(text = ufs[[1]]) )
+ }
> utility.fns[[1]](1)
[1] 2
fixes the issue. Obviously I can't manually override every time!
The reason why it always returns utility.fns[[3]]
is because if you check utility.fns
utility.fns[[1]]
#function(x){
# eval( parse(text = ufs[[i]]) )
#}
#<bytecode: 0x1223d31c8>
The i
in for loop ended at 3 so it invokes ufs[[3]]
always.
You could keep functions in ufs
itself assign the value to x
and then use eval
, parse
x <- 1
eval(parse(text = ufs[[1]]))
#[1] 2
eval(parse(text = ufs[[2]]))
#[1] 0.841
eval(parse(text = ufs[[3]]))
#[1] 0.292