2

I expect this code to set plt equal to 10:

> var = "plt"
> eval(paste0(var, "<-", 10))
[1] "plt<-10"

But instead, it returns a string.

I tried eval(as.expression(paste0(var, "<-", 10))) and other options, but it still doesn't give the expected result.

What's wrong with the code?

Anton Tarasenko
  • 8,099
  • 11
  • 66
  • 91
  • 4
    If the answer is parse() you should usually rethink the question. -- Thomas Lumley R-help (February 2005) – Roman Luštrik Dec 14 '13 at 09:57
  • What are you actually trying to do? – Thomas Dec 14 '13 at 10:02
  • @Thomas To execute a function whose name is passed to another function as an argument. Like `function(type, ...) eval(parse(text=paste0("plt <- ", type, "(...)"`. – Anton Tarasenko Dec 14 '13 at 10:06
  • 1
    @Anton In that case, please see Roland's answer. – Thomas Dec 14 '13 at 15:29
  • 2
    Usually passing the name of a function around is a very very bad thing to do. Pass the **actual** function around instead. `foo("sqrt")` is bad, since you have to jump through various hoops to get the function back. `foo(sqrt)` is better: `foo=function(f){f(2)}` neatly applies the function passed in. – Spacedman Dec 15 '13 at 10:23

2 Answers2

9

If I understand your comment correctly there is no reason to dive into the shark-infested waters of eval(parse()). Try something like this instead:

myfun <- function(x, fun) {
  if (is.character(fun)) fun <- match.fun(fun)
  fun(x)
}

myfun(1:5, mean)
#[1] 3
myfun(1:5, "mean")
#[1] 3
Roland
  • 127,288
  • 10
  • 191
  • 288
3

See: ?parse. Your demo code:

> var = "plt"
> eval(parse(text = paste0(var, "<-", 10)))
> plt
[1] 10

Update: based on @Anton's comment about the original goal - what about:

> f <- function(type, ...) {
+     assign('plt', do.call(deparse(substitute(type)), list(...)), envir = .GlobalEnv)
+ }
> f(mean, x = 1:20)
> plt
[1] 10.5

PS: I still trying to implement what the OP is after, not what he might or should be after -- that's why I used above assign and .GlobalEnv, although it's not a great idea BTW.

daroczig
  • 28,004
  • 7
  • 90
  • 124
  • 4
    @Anton Seriously, don't use this. It will result in code of very poor quality (hard to understand and maintain). There are always better alternatives to `eval(parse())`. – Roland Dec 14 '13 at 11:17