R 的 system.time 是如何工作的? [英] How does R's system.time work?

查看:26
本文介绍了R 的 system.time 是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 R 代码:

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

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

Somehow when this is executed, in the main R environment/scope:

  • time.read 有值
  • df 存在并包含正确的 data.frame

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

I thought variables created inside a function were not available outside of the function's scope? How does this work? And why after running the following does y not exist in the main R environment?

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

谢谢!

推荐答案

好问题!R 用它的参数做了一些奇怪的事情,这导致了很多混淆但也非常有用.

Great question! R does something peculiar with its argument, which causes a lot of confusion but is also very useful.

当你将一个参数传递给 R 中的函数时,它直到它实际上是在函数内部使用的.在此之前,论点只是坐在在一个名为 承诺.承诺持有表达式和它们应该被评估的环境——对于参数,这是调用者的环境.

When you pass an argument into a function in R, it doesn’t get evaluated until it’s actually used inside the function. Before that, the argument just sits around in a special container called a promise. Promises hold an expression and the environment in which they are supposed to be evaluated – for arguments, that’s the caller’s environment.

但是一旦你使用函数内部的参数,它的值就是计算.这就是 system.time 的工作原理.简化:

But as soon as you use the argument inside the function, its value is computed. This is how system.time works. Simplified:

system.time = function (expr) {
    before = proc.time()
    expr
    proc.time() - before
}

换句话说,该函数只是简单地记录时间,然后再查看它的争论.然后它查看它的参数,从而导致它的评估,并且然后它记录经过的时间.但请记住,评价参数发生在调用者的范围内,所以在你的情况下赋值 (df) 在父作用域中也是可见的.

In other words, the function simply records the time before looking at its argument. Then it looks at its argument and thus causes its evaluation, and then it records the time elapsed. But remember that the evaluation of the argument happens in the caller’s scope, so in your case the target of the assignment (df) is also visible in the parent scope.

在你的第二个例子中,你的函数 fx 从不查看它的参数,所以它永远不会被评估.您可以轻松更改它,强制对其进行评估参数,只需使用它:

In your second example, your function fx never looks at its argument, so it never gets evaluated. You can easily change that, forcing the evaluation of its argument, simply by using it:

fx <- function(z) {
    z
    return(1)
}

其实R有一个特殊的功能——force 为此目的:

In fact, R has a special function – force for this purpose:

fx <- function(z) {
    force(z)
    return(1)
}

但是force只是一个语法糖,它的定义就是简单的返回它的论点:

But force is simply syntactic sugar, and its definition is simply to return its argument:

force = function (x) x

R 不立即评估其参数的事实很有用,因为您也可以在函数内检索未计算的形式.这被称为非标准评估,有时用于评估不同范围内的表达式(使用 eval 函数及其参数 envir 指定),或检索有关未评估的信息,表达.

The fact that R doesn’t evaluate its arguments immediate is useful because you can also retrieve the unevaluated form inside the function. This is known as non-standard evaluation, and it’s sometimes used to evaluate the expression in a different scope (using the eval function with its argument envir specified), or to retrieve information about the unevaluated, expression.

许多函数都使用这个,最突出的是plot,猜测默认基于绘制的变量/表达式的轴标签:

Many functions use this, most prominently plot, which guesses default axis labels based on the plotted variables/expressions:

x = seq(0, 2 * pi, length.out = 100)
plot(x, sin(x))

现在轴标签是 xsin(x).plot 函数知道这一点,因为在其中,它可以查看其函数参数的未计算表达式:

Now the axis labels are x and sin(x). The plot function knows this because inside it, it can look at the unevaluated expressions of its function arguments:

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

substitute 检索未计算的表达式.deparse 将其转换为字符串表示.

substitute retrieves the unevaluated expression. deparse converts it into a string representation.

这篇关于R 的 system.time 是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆