我不明白为什么R中的全局范围列表无法在函数内修改,如下所示:
global <<- list()
f <- function(x) {
global[[x]] <- "blah"
}
f(1)
f(2)
print(global)
输出
list()
但是,我期待输出:
[[1]]
[1] "blah"
[[2]]
[1] "blah"
这是为什么?我是否必须声明列表中的每个元素都是全局的?
对于在功能块之外声明的局部范围变量,似乎也是如此。
谢谢!
答案 0 :(得分:3)
我相信你对Map
实际做的事情感到有点困惑。来自<<-
:
运营商&lt;&lt; - & - &gt;&gt;通常只用于函数,和 导致搜索通过父环境进行搜索 被分配的变量的定义。如果找到这样的变量 (并且它的绑定没有被锁定)然后重新定义它的值,否则 任务发生在全球环境中。
因此,应该清楚help("<<-")
无论在何处运行都不会创建“全局变量”。实际上,这根本不是R的工作方式。
相反,<<-
执行一种“全局赋值”,允许您修改当前范围之外的变量。
这是更精确<<-
的粗略版本。通常不鼓励使用这两种工具,因为它们倾向于破坏R使用的功能编程范例(即没有副作用)。与其他任何东西一样,它们都有它们的用途,但通常不用于常规变量处理。
答案 1 :(得分:2)
基本上,由于您使用的是“&lt; - ”赋值,因此该函数正在创建“全局”变量的副本,以便在函数范围内使用。
这可以通过添加第二个函数g()来看出,该函数在用f()打印之前改变'global'的值,但这次使用“&lt;&lt;&lt; - ”赋值。 f()中的第一行为f(x)创建本地范围的'global'副本,然后使用g(x)更新'global'的全局副本。
global <<- list()
f <- function(x) {
global[[x]] <- "blah"
g(x)
global
}
g <- function(x){
global[[x]] <<- "newblah"
}
f(1) #prints 'blah', despite the fact the g(x) has already updated the value
global #prints 'newblah'
如果f(x)仍然引用'global'的全局副本,它将打印以g(x)分配的“newblah”。相反,它将f(x)中指定的值打印到“global”的本地范围副本。
然而,在任何函数之外打印'global'表明g(x)确实更新了'global'全局副本的值。
现在,如果你在f(x)中移动g(x),那么f(x)现在是g(x)的父级。在这种情况下,“&lt;&lt; - ”指定在f(x)范围内的'global'的值。所以'global'的全局副本仍然是空的,但是如果你在f()的范围内打印出'global',你会得到更新的值。
global <<- list()
f <- function(x) {
global[[x]] <- "blah"
g <- function(x){
global[[x]] <<- "newblah"
}
g(x)
global
}
f(1) #prints 'newblah'
global #empty