0

I need to change the body of a function depending on input given by users.

modelstring <- function() {
  for (h in (l1i1[j]):(l1i2[j])) {
    w[h] <- 1/l1n[h]
  }
}

userinput <- "b.w[1]*X.w[i,1]^exp(b.w[2]*X.w[i,2])"

body(modelstring)[[2]][[4]][[2]][[3]] <- userinput 

The problem is that the changed function includes quotation marks. How do I get rid of them?

modelstring

function () 
{
    for (h in (l1i1[j]):(l1i2[j])) {
        w[h] <- "b.w[1]*X.w[i,1]^exp(b.w[2]*X.w[i,2])"
    }
}

When evaluating the user input as formula, the replacement works and no quotation marks are inserted

userinput <- as.formula(w ~ b.w[1]*X.w[i,1]^exp(b.w[2]*X.w[i,2]))

However, I need to use <- or just the right-hand side. In those cases, the formula is evaluated, which gives an error.

I have also tried noquote which still gives quotation marks:

userinput <- noquote("b.w[1]*X.w[i,1]^exp(b.w[2]*X.w[i,2])")

Finally, I have tried different combinations of expr(!!userinput), subs(), and substitute.

Ben
  • 197
  • 1
  • 9

1 Answers1

2

Assuming that the desired inputs are

  1. the modelstring function and
  2. the text of the replacement as a character string, userinput

use parse to convert the string to an expression and then add [[1]] on the end to convert that from an expression to a call object:

userinput <- "b.w[1]*X.w[i,1]^exp(b.w[2]*X.w[i,2])" # as in question
body(modelstring)[[2]][[4]][[2]][[3]] <- parse(text = userinput)[[1]]

modelstring
## function () 
## {
##     for (h in (l1i1[j]):(l1i2[j])) {
##         w[h] <- b.w[1] * X.w[i, 1]^exp(b.w[2] * X.w[i, 2])
##     }
## }

Here is a simpler example that may be useful to play around with:

# inputs
f <- function() { 37 }
s <- "pi * pi"

body(f)[[2]] <- parse(text = s)[[1]]
f()
## [1] 9.869604
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341