gpt4 book ai didi

r - 赋值以替换非本地列表中的值

转载 作者:行者123 更新时间:2023-12-03 14:19:45 28 4
gpt4 key购买 nike

[[<-当用于非本地对象时,列表和环境的行为不同:

lst = list()
env = new.env()

(function () lst[['x']] = 1)()
(function () env[['x']] = 1)()
lst
# list()

as.list(env)
# $x
# [1] 1

换句话说,如果 [[<- 的目标是一个环境,它修改(非本地)环境,但如果它是一个向量/列表,它会创建一个新的本地对象。

我想知道两件事:
  • 为什么会有这种行为差异?
  • 有没有一种方法可以在不使用 <<- 的情况下为列表实现与环境相同的结果? ?

  • 关于(1) ,我知道列表和环境之间的多重差异(特别是,我知道环境不会被复制)但文档没有提到为什么 [[<- 的语义两者之间的差异——特别是,为什么运营商会在不同的范围内运作。这是一个错误吗?这至少是违反直觉的,并且需要一些不平凡的实现恶作剧。 1

    关于(2) ,显而易见的解决方案当然是使用 <<- :
    (function () lst[['x']] <<- 1)()

    但是,我更喜欢严格理解差异,而不是仅仅解决它们。此外,到目前为止,我使用了 assign而不是 <<-我更喜欢这个,因为它可以让我更好地控制分配的范围(特别是因为我可以指定 inherits = FALSE<<- 对我来说太巫毒了。

    但是,使用 assign 无法解决上述问题(据我所知)因为 assign仅适用于环境,不适用于列表。特别是,虽然 assign('x', 1, env)工作(和上面一样), assign('x', 1, lst)不起作用。

    1
    详细地说,当然希望 R 使用动态调度(例如通过 S3)为不同的对象类型做不同的事情。然而,这里不是这种情况(至少不是直接的):作用域解析的区别发生在分配目标的对象类型已知之前——否则上述将在全局 lst 上运行,而不是创建一个新的本地对象。所以在内部 [[<-必须做相当于:
    `[[<-` = function (x, i, value) {
    if (exists(x, mode = 'environment', inherits = TRUE))
    assign(i, value, pos = x, inherits = FALSE)
    else if (exists(x, inherits = FALSE)
    internal_assign(x, i, value)
    else
    assign(x, list(i = value), pos = parent.frame(), inherits = FALSE)
    }

    最佳答案

    R-language definition (第 2.1.10 节)说:

    Unlike most other R objects, environments are not copied when passed to functions or used in assignments.



    “6.3 更多关于评估”部分也给出了一个稍微相关的提示:

    Notice that evaluation in a given environment may actually change that environment, most obviously in cases involving the assignment operator, such as

    eval(quote(total <- 0), environment(robert$balance)) # rob Rob

    This is also true when evaluating in lists, but the original list does not change because one is really working on a copy.



    因此,第一个问题的答案是需要复制列表以分配给它们,但是可以就地修改环境(这对性能有很大影响)。

    关于你的第二个问题:

    如果您正在使用列表,唯一的选择似乎是
  • 将列表复制到本地范围(使用 get ),
  • 分配到列表中,
  • 使用 assign将修改后的列表复制回原始环境。
  • 关于r - 赋值以替换非本地列表中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31476340/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com