我有一些R代码:
time.read = system.time(df <- data.frame(fread(f)))
print(class(time.read))
#[1] "proc_time"
print(class(df))
#[1] "data.frame"
以某种方式执行此操作时,在主R环境/范围中:
我认为函数内部创建的变量在函数范围之外是不可用的?这是如何运作的?为什么运行以下内容后主R环境中不存在?
fx <- function(z){return(1)}
out = fx(y <- 300)
print(out)
#[1] 1
print(y)
#Error in print(y) : object 'y' not found
谢谢!
答案 0 :(得分:18)
好问题! R做了一些与其论证特有的东西,这引起了很多 混乱,但也非常有用。
当您将参数传递给R中的函数时,直到它才会进行评估 它实际上是在函数内部使用的。在此之前,争论就在于此 在一个名为 promise 的特殊容器中。承诺举行 表达和他们应该被评估的环境 - 为 参数,这是调用者的环境。
但是只要你在函数内部使用参数,它的值就是
计算。这就是system.time
的工作原理。简化为:
system.time = function (expr) {
before = proc.time()
expr
proc.time() - before
}
换句话说,该功能只是在查看它之前记录时间
论点。 然后它查看其参数,从而导致其评估,并且
然后它记录经过的时间。但要记住评价
参数发生在调用者的范围内,所以在你的情况下是目标
在父作用域中也可以看到作业(df
)。
在你的第二个例子中,你的函数fx
从不查看它的参数,所以它
永远不会被评估。您可以轻松更改它,强制对其进行评估
论证,只需使用它:
fx <- function(z) {
z
return(1)
}
事实上,R有一个特殊功能 - force
用于此目的:
fx <- function(z) {
force(z)
return(1)
}
但是force
只是语法糖,它的定义只是返回
它的论点:
force = function (x) x
R不会立即评估其参数的事实是有用的,因为你
还可以检索函数内未评估的表单。这被称为
non-standard evaluation ,它有时用于评估
表达式在不同的范围内(使用eval
函数及其表达式
参数envir
指定),或检索有关未评估的信息,
表达
许多函数使用这个,最突出的是plot
,它猜测默认值
轴标签基于绘制的变量/表达式:
x = seq(0, 2 * pi, length.out = 100)
plot(x, sin(x))
现在轴标签为x
和sin(x)
。 plot
函数知道这个因为
在它内部,它可以查看其函数参数的未评估表达式:
xlabel = deparse(substitute(x))
ylabel = deparse(substitute(y))
substitute
检索未评估的表达式。
deparse
将其转换为字符串表示形式。