【问题标题】:return(q * log(..)) in a function returns error函数中的 return(q * log(..)) 返回错误
【发布时间】:2013-12-08 23:02:54
【问题描述】:

我正在构建一个函数,该函数在调用代码中使用名为 q 的变量并返回 q * log(.. some number .. )。 在会话中创建此功能时,它可以正常工作,但是在另一个会话中加载包后使用此功能创建包时,它不起作用。这是一个简化的例子

在 R 中:

>myfunc <- function() return(q * log(2.0))
>q=1.0
>myfunc()
[1] 1.386294
>package.skeleton(list=c("myfunc"),name="mypckg")

在 R 中再次构建和安装包之后

> library(mypckg)
> q = 3.0
> myfunc()
Erreur dans q * log(2) : argument non numérique pour un opérateur binaire

如果我将变量的名称从 q 修改为 qq 或任何其他名称,一切正常。

谁能解释发生了什么。 q 是某个保留名称吗?这是 R 中的某个已知错误吗?

【问题讨论】:

  • q是终止当前R会话的函数
  • 不要写return(…),如果这是函数中唯一的返回路径。 R是函数式语言,写function () q * log(2.0)
  • 对不起,无论是否返回,错误仍然存​​在!
  • @KonradRudolph 虽然是真的,但使用return 语句来明确返回什么是一种很好的编码习惯,更不用说在函数体中添加某些内容时避免意外返回不想要的内容。跨度>
  • @mike:你想错了。尝试将您的对象重命名为“qqqqq”,然后查看您收到的错误消息。

标签: r


【解决方案1】:

当您将函数包装在一个包中时,它与包含该包的剩余代码不同,它存在于另一个环境中。因此,myfunc 正在为 q 搜索一组不同的环境,而不是你的变量,它找到了 base::q,这是一个函数。

解决方案是不要像在函数中那样访问全局变量。而是使用参数:

myfunc <- function (q) q * log(2.0)

【讨论】:

  • 澄清一下:R 将没有括号的函数解释为打印函数的请求。所以 myfunc “看到” function (save = "default", status = 0, runLast = TRUE) .Call("RappQuit", save, status, runLast) &lt;environment: 0x100fe19f0&gt; * log(2.0) 和该文本上的 barfs。
  • Konrad:我知道,这个例子只是一个简化的例子。我的原始函数有一个参数向量作为参数,该向量需要由 nlminb 修改,该向量仅适用于一个参数函数,因此在这种情况下,没有地方可以放置具有两个参数 myfunc(param, q) 的函数。在这种情况下,我的函数需要访问全局变量...
  • @Carl 字符串转换从何而来?我认为这里不会发生这种情况:q 不在会发生这种转换的上下文中,实际上即使没有这种转换也会发生相同的错误:例如,尝试list() * 2 得到相同的错误. * 根本没有为非数字参数定义。
  • @mike 不,他们不需要需要访问全局变量。重写这个,以这种方式让包共享变量通常被认为是不可接受的糟糕设计。使用类或其他共享状态的机制,但使用全局变量不起作用。
  • @Carl 其实我只是因为好奇才查的。它不会“将没有括号的函数解释为打印函数的请求”。相反,它将函数原样传递给*,后者又调用.Primitive('*'),后者又在C代码中调用do_arith,最后调用R_binaryAnd there, finally 检查其参数是否为数字,如果失败,则报告错误。
【解决方案2】:

如果您希望在重用函数时提供“q”值,您有两种选择:在参数列表中使用它或在函数体中定义它以便保留它。

myfunc <- function(q=1.0) return(q * log(2.0))
myfunc()

或者:

myfunc <- function() {q<-1.0; q * log(2.0) }  # less flexible definition of q
myfunc()

Jörg Mäder 的评论指出错误消息表明它确实找到了“q”,只是不在命名数据对象列表中,而是在命名函数列表中。

【讨论】:

  • @Jorg: q 来自在主脚本中读取的数据,它是一个我事先不知道其大小的向量。我不清楚这有什么帮助...
  • 通过参数列表将 'q' 传递给函数有什么问题?
  • 正如我已经评论过另一个答案:我的原始函数(更复杂)有一个参数向量作为参数,需要由 nlminb 修改,它只适用于一个参数函数,所以没有在这种情况下放置一个带有两个参数的函数 myfunc(param, q)。在这种情况下,我的函数需要访问全局变量..
  • 你应该把需要的信息放在问题中,这就是编辑按钮的作用。
  • 我不明白你的意思我应该难过我的原始函数不是 myfunction() 但实际上 myfunction(params) 是一个向量,需要通过 nlminb 优化??
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 1970-01-01
相关资源
最近更新 更多