<- 和 <<- 的区别
Difference between <- and <<-
案例 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
函数的环境, <<-
可以初始化函数外的对象还是当前环境中的对象?完全混淆什么时候使用 <-
什么时候使用 <<-
。
运算符<<-
是父作用域赋值运算符。它用于将 最近的 父范围内的变量赋值到对其进行评估的范围。因此,这些赋值 "stick" 在函数调用之外的范围内。考虑以下代码:
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
"sticks"的赋值是在函数求完之后。 R 实际上做的是遍历 fun2()
之外的所有作用域,并寻找包含名为 x
的变量的 第一个 作用域。在这种情况下,fun2()
之外的唯一范围是全局范围,因此它在那里进行分配。
正如一些人已经评论的那样,<<-
运算符被许多人反对,因为它会破坏 R 脚本的封装。如果我们将 R 函数视为一个孤立的功能块,那么不应允许它干扰调用它的代码的状态。滥用 <<-
赋值运算符存在这样做的风险。
<<-
运算符可用于将变量分配给全局环境。使用 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
有了赋值功能,
f <- function(x) {
assign('y', x*2 envir=.GlobalEnv)
}
f(5) # y = 10
案例 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
函数的环境, <<-
可以初始化函数外的对象还是当前环境中的对象?完全混淆什么时候使用 <-
什么时候使用 <<-
。
运算符<<-
是父作用域赋值运算符。它用于将 最近的 父范围内的变量赋值到对其进行评估的范围。因此,这些赋值 "stick" 在函数调用之外的范围内。考虑以下代码:
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
"sticks"的赋值是在函数求完之后。 R 实际上做的是遍历 fun2()
之外的所有作用域,并寻找包含名为 x
的变量的 第一个 作用域。在这种情况下,fun2()
之外的唯一范围是全局范围,因此它在那里进行分配。
正如一些人已经评论的那样,<<-
运算符被许多人反对,因为它会破坏 R 脚本的封装。如果我们将 R 函数视为一个孤立的功能块,那么不应允许它干扰调用它的代码的状态。滥用 <<-
赋值运算符存在这样做的风险。
<<-
运算符可用于将变量分配给全局环境。使用 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
有了赋值功能,
f <- function(x) {
assign('y', x*2 envir=.GlobalEnv)
}
f(5) # y = 10