Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 为什么在system.time()中计算表达式会使变量在全局环境中可用?_R_Scope - Fatal编程技术网

R 为什么在system.time()中计算表达式会使变量在全局环境中可用?

R 为什么在system.time()中计算表达式会使变量在全局环境中可用?,r,scope,R,Scope,有人能解释一下在system.time中计算表达式时会发生什么吗?特别是,为什么在expr参数中声明的变量在全局环境中可见 下面是system.time内部的精简版本,它除了计算传递给函数的表达式外,什么都不做: st <- function(expr){ expr } st(aa <- 1) aa [1] 1 st我认为expr是在处理函数之前进行评估的。POC示例: > st <- function(expr){ + eval(parse(text=exp

有人能解释一下在
system.time
中计算表达式时会发生什么吗?特别是,为什么在
expr
参数中声明的变量在全局环境中可见

下面是
system.time
内部的精简版本,它除了计算传递给函数的表达式外,什么都不做:

st <- function(expr){
  expr
}

st(aa <- 1)
aa
[1] 1
st我认为
expr
是在处理函数之前进行评估的。POC示例:

> st <- function(expr){
+   eval(parse(text=expr))
+ }
> 
> st('aa <- 1')
> aa
Error: object 'aa' not found
我可能错了,这是一种直觉:)但谢谢,这是一个很好的谜题


更新:

> system.time(a <- 1)
   user  system elapsed 
      0       0       0 
> a
[1] 1
> rm(a)
> fn <- function() a <- 1
> system.time(fn())
   user  system elapsed 
      0       0       0 
> a
Error: object 'a' not found
>系统时间(a)
[1] 1
>rm(a)
>fn a
错误:找不到对象“a”

这是因为提供的参数在调用函数的求值框架中求值(如R语言定义文档的中所述)

用户在
system.time()
中包装的表达式是一个提供的参数,它在位置上与
expr
匹配。然后,当
expr
的求值被强制在
system.time
的主体中时,它将在调用函数的求值框架中求值。如果
system.time()
是从
.GlobalEnv
调用的,这是执行
expr
中的任何赋值的地方

编辑:

> system.time(a <- 1)
   user  system elapsed 
      0       0       0 
> a
[1] 1
> rm(a)
> fn <- function() a <- 1
> system.time(fn())
   user  system elapsed 
      0       0       0 
> a
Error: object 'a' not found
下面的示例显示,如果
expr
提供的(但不是默认)参数,则在全局环境中对其进行计算

st2 <- function(expr = newVar <- 33){
   expr
}

# Using the default argument -- eval and assignment 
# within evaluation frame of the function. 
st2()
newVar
Error: object 'newVar' not found

# Using a supplied argument -- eval and assignment
# within the calling function's evaluation frame (here .GlobalEnv)
st2(newVar <- 44)
newVar
# [1] 44

st2EDIT:根据@Tommy的注释:实际上,只有在使用参数expr时,才会进行计算(这是延迟计算)


传递的是一个语言对象,而不是表达式。基本上,您将
嵌套在
系统的源代码中。时间
您会注意到
expr
仅在执行多个内务管理活动(例如启动时钟)后才会计算。您修改的函数将字符串作为输入,而不是一点代码(和
system.time
)一样。@Andrie:没错,以后可以在
system.time
中找到
expr
,但这并不影响我答案的基本思想。请参阅更新的示例。我可以相信你的话,但如果你能在R手册中找到参考,我会奖励你分数。:-,呃,你的答案(+1)对我的直觉来说似乎要明确得多:)@Andrie——我想感谢你提出了这个有趣的问题。我对R语言定义的超级链接算是对R手册的引用吗?;)+1您的手册链接一点也不模糊,非常有用。谢谢。说
aa是不正确的……还要注意
typeof(expr)
计算
expr
以检查其类型。
st(mean(1:10))
st <- function(expr){
  typeof(expr)
}
> st(aa <- 1)
[1] "double"
> st(expression(aa <- 1))
[1] "expression"
st <- function(expr){
  str(as.list(match.call()))
}
> st(mean(1:10))
List of 2
 $     : symbol st
 $ expr: language mean(1:10)
> st(aa <- 1)
List of 2
 $     : symbol st
 $ expr: language aa <- 1