x ls() [1] "rel.mem" "x" > rel.mem(x) > ls() [1] "rel.mem" "x" -6ren">
gpt4 book ai didi

r - 为什么函数内部的 rm 不删除对象?

转载 作者:行者123 更新时间:2023-12-04 16:58:36 25 4
gpt4 key购买 nike

rel.mem <- function(nm) {
rm(nm)
}

我定义了上面的函数 rel.mem——接受一个参数并将它传递给 rm
> ls()
[1] "rel.mem"
> x<-1:10
> ls()
[1] "rel.mem" "x"
> rel.mem(x)
> ls()
[1] "rel.mem" "x"

现在你可以看到我所说的 rel.mem x 没有被删除——我知道这是由于尝试 rm 的环境不正确。

有什么好的解决方法?

良好修复的标准:
  • 调用者不必传递环境
  • 被调用者(rel.mem)应该能够通过使用 R 语言工具(调用堆栈检查、方面等)来确定环境
  • 函数 rel.mem 的接口(interface)应该保持简单——傻瓜证明:调用 rel.mem——然后 rel.mem 从那里获取它——不需要传递环境。

  • 笔记:
  • 正如许多评论者所指出的,一个简单的解决方法是通过环境。
  • 我所说的一个好的修复[我应该澄清它]的意思是被调用函数(在本例中为 rel.mem)能够计算/找出调用者引用的环境,然后从正确的环境。
  • “2”中的推理类型可以在其他语言中通过检查调用堆栈来完成——例如在 Java 中我会抛出一个虚拟异常——捕获它然后解析调用堆栈。在其他语言中,我仍然可以使用面向方面的技术。问题是这样的事情可以在 R 中完成吗?
  • 正如一位评论者所暗示的那样,可能有多个具有相同名称的对象,因此“正确”的环境是没有意义的——正如我在上面所说的那样,在其他语言中,有可能(有时带有一些创造性的技巧)来解释调用-stack -- 这在 R
  • 中可能是不可能的
  • 正如一位评论者所建议的那样, rm(list=nm, envir = parent.frame()) 将从父环境中删除它。这是正确的——但是我正在寻找适用于任意调用深度的东西。
  • 最佳答案

    快速的答案是您处于不同的环境中 - 基本上将变量描绘在一个框中:您有一个用于函数的框和一个用于全局环境的框。你只需要告诉rm在哪里可以找到那个盒子。

    所以

    rel_mem <- function(nm) {
    # State the environment
    rm(list=nm, envir = .GlobalEnv )
    }
    x = 10
    rel_mem("x")

    或者,您可以使用 pos论据,例如
    rel_mem <- function(nm) {
    rm(list=nm, pos=1 )
    }

    如果您键入 search()你会看到一个环境向量,全局是数字 1 .

    另外两个选项是
  • envir = parent.frame()如果你想上一层调用堆栈
  • 使用inherits = TRUE向上调用堆栈,直到找到


  • 在上面的代码中,请注意我将对象作为字符传递 - 我传递了 "x"不是 x .我们可以很聪明地使用 substitute 来避免这种情况。功能
    rel_mem <- function(nm) {
    rm(list = as.character(substitute(nm)), envir = .GlobalEnv )
    }

    最后,我将在 .GlobalEnv 中添加删除内容。来自函数的一般是 主意。

    更多资源:
  • 环境:http://adv-r.had.co.nz/Environments.html
  • 代入功能:http://adv-r.had.co.nz/Computing-on-the-language.html#capturing-expressions
  • 关于r - 为什么函数内部的 rm 不删除对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39297737/

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