R的system.time如何运作?

时间:2014-12-03 11:06:58

标签: r scope

我有一些R代码:

time.read = system.time(df <- data.frame(fread(f)))
print(class(time.read))
#[1] "proc_time"
print(class(df))
#[1] "data.frame"

以某种方式执行此操作时,在主R环境/范围中:

  • time.read有一个值
  • df存在且​​包含正确的data.frame

我认为函数内部创建的变量在函数范围之外是不可用的?这是如何运作的?为什么运行以下内容后主R环境中不存在?

fx <- function(z){return(1)}
out = fx(y <- 300)
print(out)
#[1] 1
print(y)
#Error in print(y) : object 'y' not found

谢谢!

1 个答案:

答案 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))

现在轴标签为xsin(x)plot函数知道这个因为 在它内部,它可以查看其函数参数的未评估表达式:

xlabel = deparse(substitute(x))
ylabel = deparse(substitute(y))

substitute检索未评估的表达式。 deparse将其转换为字符串表示形式。