在环境中分配列表属性

时间:2011-07-16 02:15:47

标签: r environment

标题是一个独立的问题。一个例子澄清了它:考虑

x=list(a=1, b="name")
f <- function(){
    assign('y[["d"]]', FALSE, parent.frame() )
}
g <- function(y) {f(); print(y)}

g(x)

$a
[1] 1

$b
[1] "name"

而我想得到

g(x)

$a
[1] 1

$b
[1] "name"

$d
[1] FALSE

一些评论。我知道我的原始例子中有什么问题,但我用它来明确我的目标。我想避免&lt;&lt; - ,并希望在父框架中更改x。

我认为我对环境的理解是原始的,任何引用都会受到赞赏。

2 个答案:

答案 0 :(得分:6)

assign的第一个参数必须是变量名,而不是表达式的字符表示。尝试将f替换为:

f <- function() with(parent.frame(), y$d <- FALSE)

请注意,abd是列表组件,而不是列表属性。如果我们想在"d"的父框架中向y添加属性f,我们会这样做:

f <- function() with(parent.frame(), attr(y, "d") <- FALSE)

另外,请注意,根据您想要做的事情,将x作为环境或proto对象(来自proto包)可能(或可能不)更好。

答案 1 :(得分:3)

assign的第一个参数需要是一个对象名称。您对assign的使用与分配帮助页面末尾的计数器示例基本相同。观察:

> x=list(a=1, b="name")
> f <- function(){
+     assign('x["d"]', FALSE, parent.frame() )
+ }
> g <- function(y) {f(); print(`x["d"]`)}
> g(x)
[1] FALSE   # a variable with the name `x["d"]` was created

这可能是您想要使用“&lt;&lt; - ”的地方,但通常被认为是可疑的。

> f <- function(){
+     x$d <<- FALSE
+ }
> g <- function(y) {f(); print(y)}
> g(x)
$a
[1] 1

$b
[1] "name"

$d
[1] FALSE

进一步的想法是,在没有任何目标进行这项练习而忽略了Gabor指出的“属性”一词在R中具有特定含义,但可能不是你的目标。如果你想要的只是符合你的规格的输出,那么这就达到了这个目标,但注意到全球环境中没有发生x的变化。

> f <- function(){
+     assign('y', c(x, d=FALSE), parent.frame() )
+ }
> g <- function(y) {f(); print(y)}
> g(x)
$a
[1] 1

$b
[1] "name"

$d
[1] FALSE

> x    # `x` is unchanged
$a
[1] 1

$b
[1] "name"

f的parent.frame可称为“g的内部”,但更改不会传播到全局环境。