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)
如果编写不带参数的函数或者功能依赖于当前帧之外的变量范围,则这只是一个问题.你要么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,这在您的发布和评论中并不明确.如果您想要做的就是随机返回10或NA定义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代码的一个例子,也不应该是这样的.请相应地了解范围界定功能和代码,并且不会被咬.你甚至可能发现你可以利用这个功能......