do.call和curve无法在另一个函数环境中绘制函数 [英] do.call and curve can not plot a function inside another function environment

查看:106
本文介绍了do.call和curve无法在另一个函数环境中绘制函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到有关 do.call 曲线的奇怪问题:

func1 <- function (m, n) {
  charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
  eval(parse(text = charac))
  return(func2)
}
func3 <- function (m, n) {
  my.func <- func1 (m, n)
  do.call("curve",list(expr = substitute(my.func)))
}

func1 构造 func2 ,而 func3 绘制构造的 func2 . 但是当我运行 func3 时,将显示以下错误:

> func3 (3, 6)
Error in curve(expr = function (x)  : 
  'expr' must be a function, or a call or an expression containing 'x'

但是,当我运行 func1 并手动绘制输出(不应用 func3 )时,会绘制 func2 :

my.func <- func1 (3, 6)
do.call("curve",list(expr = substitute(my.func)))

这里发生的事情使我感到困惑,我不知道为什么 do.call 不能在 func3 本地环境中绘制 func2 .

谢谢

解决方案

这不是do.call的问题,而是substitute ,它在全局环境中默认评估. 所以,您需要告诉它必须在哪个环境中进行替换.这里显然在func3的本地环境中.

这应该有效:

 do.call("curve",list(expr = substitute(my.func,
                                           env = parent.frame())))

编辑,谢谢Dwin

如注释替代中所述,env默认为当前评估环境.那么,为什么下面的代码有效?在substitute

的帮助下的答案

函数的形式参数或使用显式创建的形式参数 delayAssign(),promise的表达槽替换了 象征.如果它是一个普通变量,则将其值替换, 除非env是.GlobalEnv,否则该符号将保持不变.

env = parent.frame(n=1)等效于.GlobalEnv,这就是为什么符号(my.func)保持不变的原因.因此正确的答案是:

do.call("curve",list(expr = substitute(my.func,
                                               env = .GlobalEnv)))

要测试,我打开了一个新的R会话:

func1 <- function (m, n) {
  charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
  eval(parse(text = charac))
  return(func2)
}
func3 <- function (m, n) {
  my.func <- func1 (m, n)

  do.call("curve",list(expr = substitute(my.func,env = .GlobalEnv)))
}

比我打电话

 func3(2,6)

I am facing a strange problem about do.call and curve:

func1 <- function (m, n) {
  charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
  eval(parse(text = charac))
  return(func2)
}
func3 <- function (m, n) {
  my.func <- func1 (m, n)
  do.call("curve",list(expr = substitute(my.func)))
}

func1 constructs func2 and func3 plots the constructed func2. But when I run func3, following error would be displayed:

> func3 (3, 6)
Error in curve(expr = function (x)  : 
  'expr' must be a function, or a call or an expression containing 'x'

However, while I run func1 and plot the output manually (without applying func3), func2 would be plotted:

my.func <- func1 (3, 6)
do.call("curve",list(expr = substitute(my.func)))

What happened here leads me to a confusion and I do not know why do.call can not plot func2 inside func3 local environment.

Thank you

解决方案

It is not a problem of do.call, but substitute which evaluate by default in the global environment. So you need to tell it in which environment substitution must occur. Here obviously in the local envir of func3.

This should work:

 do.call("curve",list(expr = substitute(my.func,
                                           env = parent.frame())))

Edit thanks Dwin

As said in the comment substitute env Defaults to the current evaluation environment. So Why the code below works? The answer in the help of substitute

formal argument to a function or explicitly created using delayedAssign(), the expression slot of the promise replaces the symbol. If it is an ordinary variable, its value is substituted, unless env is .GlobalEnv in which case the symbol is left unchanged.

env = parent.frame(n=1) is equivalent to .GlobalEnv, that why the symbol (my.func) is left unchanged. So the correct answer would be :

do.call("curve",list(expr = substitute(my.func,
                                               env = .GlobalEnv)))

To test , I open new R session :

func1 <- function (m, n) {
  charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
  eval(parse(text = charac))
  return(func2)
}
func3 <- function (m, n) {
  my.func <- func1 (m, n)

  do.call("curve",list(expr = substitute(my.func,env = .GlobalEnv)))
}

Than I call

 func3(2,6)

这篇关于do.call和curve无法在另一个函数环境中绘制函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆