案例1:
rm(list = ls())
foo <- function(x = 6){
set <- function(){
x <- x*x}
set()
x}
foo()
# [1] 6
案例2:
rm(list = ls())
foo <- function(x = 6){
set <- function(){
x <<- x*x}
set()
x}
foo()
# [1] 36
我读到<<-
运算符可用于为不同于当前环境的环境中的对象赋值。它表示使用<<-
进行对象初始化可以对不在当前环境中的对象进行。我想问一下使用<<-
可以初始化哪个环境的对象。在我的情况下,环境是foo
函数的环境,可以<<-
初始化函数外部的对象或当前环境中的对象吗?完全混淆何时使用<-
以及何时使用<<-
。
答案 0 :(得分:8)
运算符<<-
是父作用域赋值运算符。它用于将最近父作用域中的变量赋值给它所评估的作用域。因此,这些分配“粘在”函数调用之外的范围内。请考虑以下代码:
fun1 <- function() {
x <- 10
print(x)
}
> x <- 5 # x is defined in the outer (global) scope
> fun1()
[1] 10 # x was assigned to 10 in fun1()
> x
[1] 5 # but the global value of x is unchanged
在函数fun1()
中,本地变量x
分配给值10
,但在全局范围内x
的值没有改变。现在考虑重写函数以使用父作用域赋值运算符:
fun2 <- function() {
x <<- 10
print(x)
}
> x <- 5
> fun2()
[1] 10 # x was assigned to 10 in fun2()
> x
[1] 10 # the global value of x changed to 10
因为函数fun2()
使用<<-
运算符,所以在函数完成评估后,x
“的赋值会”粘住“。 R实际上做的是遍历fun2()
之外的所有范围,并查找包含名为x
的变量的第一个范围。在这种情况下,fun2()
之外的唯一范围是全局范围,因此它在那里进行分配。
正如一些人已经评论过的那样,<<-
运算符被许多人所厌恶,因为它可以打破R脚本的封装。如果我们将R函数视为一个独立的功能,则不应该允许它干扰调用它的代码的状态。滥用<<-
赋值运算符会冒这样做的风险。
答案 1 :(得分:2)
<<-
运算符可用于将变量分配给全局环境。最好使用assign
函数而不是<<-
。您可能不需要使用<<-
- 函数所需的输出应作为R中的对象返回。
这是一个例子
f <- function(x) {
y <<- x * 2 # y outside the function
}
f(5) # y = 10
这相当于
f <- function(x) {
x * 2
}
y <- f(5) # y = 10
使用assign函数
f <- function(x) {
assign('y', x*2 envir=.GlobalEnv)
}
f(5) # y = 10