R的本地/全球问题是什么?

Geo*_*off -2 programming-languages r

在以下示例的什么情况下返回本地x与全局x?

xi'an博客在http://xianblog.wordpress.com/2010/09/13/simply-start-over-and-build-something-better/上写了以下内容:

范围最严重的问题之一是范围界定.考虑以下小宝石.

f =function() {
if (runif(1) > .5)
x = 10
x
}
Run Code Online (Sandbox Code Playgroud)

此函数返回的x是随机本地或全局的.还有其他示例,其中变量在函数体内的局部变量和非局部变量之间交替.没有明智的语言会允许这样做.它很难看,它使得优化变得非常困难.这不是唯一的问题,因为范围和懒惰评估之间的相互作用,甚至更奇怪的事情发生.

PS - 这个西安博客文章是由Ross Ihaka写的吗?

编辑 - 跟进问题.

这是补救措施吗?

f = function() {
  x = NA
  if (runif(1) > .5)
    x = 10
  x
}
Run Code Online (Sandbox Code Playgroud)

Rei*_*son 6

如果编写不带参数的函数或者功能依赖于当前帧之外的变量范围,则这只是一个问题.你要么i)在函数中传递你需要的对象作为该函数的参数,要么ii)在使用它们的函数内创建这些对象.

f的编码不正确.如果您可能改变x,那么您应该传入x,可能设置默认值NA或类似值,如果这是您想要随机翻转的另一侧.

f <- function(x = NA) {
    if (runif(1) > .5)
    x <- 10
    x
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们看到函数按照您的第二个函数工作,但通过x适当的默认值正确分配为参数.请注意,即使我们x在全局工作空间中定义了另一个:

> set.seed(3)
> replicate(10, f())
 [1] NA 10 NA NA 10 10 NA NA 10 10
> x <- 4
> set.seed(3)
> replicate(10, f())
 [1] NA 10 NA NA 10 10 NA NA 10 10
Run Code Online (Sandbox Code Playgroud)

这样做的另一个好处是,x如果你想要返回一些其他值而不是,你可以传入一个NA.如果您不需要该功能,那么x <- NA 功能中定义就足够了.

以上内容取决于您实际想要做什么f,这在您的发布和评论中并不明确.如果您想要做的就是随机返回10NA定义x <- NA.

当然,这个函数非常愚蠢,因为它无法利用R中的向量化 - 它是一个非常多的标量运算,我们知道它在R中很慢.一个更好的函数可能是

f <- function(n = 1, repl = 10) {
    out <- rep(NA, n)
    out[runif(n) > 0.5] <- repl
    out
}
Run Code Online (Sandbox Code Playgroud)

要么

f <- function(x, repl = 10) {
    n <- length(x)
    out <- rep(NA, n)
    out[runif(n) > 0.5] <- repl
    out
}
Run Code Online (Sandbox Code Playgroud)

我推测,罗斯的榜样功能是故意简单而愚蠢地强调范围问题 - 它不应该被视为编写好的R代码的一个例子,也不应该是这样的.请相应地了解范围界定功能和代码,并且不会被咬.你甚至可能发现你可以利用这个功能......