【问题标题】:Cleaning up the global environment after sourcing: How to remove objects of a certain type in R采购后清理全局环境:如何在 R 中删除某种类型的对象
【发布时间】:2015-03-27 14:28:42
【问题描述】:

我阅读了一个公共数据集,该数据集在构建最终数据框的过程中创建了数十个临时向量。由于此数据框将作为更大流程的一部分进行分析,因此我计划 sourceing 创建数据框的 R 脚本,但不想让自己或未来的用户处于混乱的全球环境中。

我知道我可以使用ls 列出全局环境中的当前对象并使用rm 删除某些对象,但我不确定如何同时使用这两个函数删除除特定脚本创建的数据框之外的所有对象

为了澄清,这里有一个可重现的例子:

脚本 1,名为“script1.R”

setwd("C:/R/project")
set.seed(12345)
var <- letters
for (i in var) {
  assign(i, runif(1))
}
df <- data.frame(x1 = a, x2 = b, x3 = c)

脚本 2

source("script1.r")

通过rmlspattern = letters 或类似的组合,从sourced 脚本中删除所有向量很容易,但我想做的是创建一个通用函数删除由某个脚本创建的所有向量,只保留数据帧(在本例中为df)。

(注意:有类似herehere的问题,但我觉得我的不同之处在于更具体地用于多脚本项目上下文中的采购和清理)。

更新 在环顾四周时,以下链接给了我一个很好的解决方法:

How can I neatly clean my R workspace while preserving certain objects?

具体来说,用户@Fojtasek 建议:

我会通过创建一个单独的环境来存储所有垃圾变量,使用 with() 制作您的数据框,然后将您想要保留的那些复制到主环境中来解决这个问题。这样做的好处是整洁,但也可以保留所有对象,以防您想再次查看它们。

所以我可以按如下方式附加创建数据框的源代码...

temp <- new.env()
with(temp, {
    var <- letters
for (i in var) {
  assign(i, runif(1))
}
df <- data.frame(x1 = a, x2 = b, x3 = c)
}

...然后将所需的数据帧 (df) 提取到我的全局环境中,但我很好奇是否还有其他优雅的解决方案,或者我是否错误地考虑了这一点。

谢谢。

【问题讨论】:

  • 您是否真的像本例中那样存储了要删除的变量的名称(通过var)?
  • 我无法测试这个 atm,因为我不在我的 R 终端前面,但由于 ls 返回一个向量,你可以在 @987654340 之前和之后做一个 ls @,然后遍历并删除除数据框之外的差异。
  • @Dason 不,我没有。它们都是以不同的方式创建的。我只是用它作为一个例子来展示你如何在你的全局环境中拥有多个用于创建数据框的向量。
  • 这有帮助吗? stackoverflow.com/questions/28142088/… 好像和你做的一样
  • 创建一个新环境,只导入你想要的,然后将所需的对象传递给全局环境,最好是从函数中返回它,这可能更有意义。

标签: r


【解决方案1】:

作为一种替代方法(类似于@Ken 对 cme​​ts 的建议),以下代码允许您删除在某个点之后创建的所有对象,除了您指定的一个(或多个)对象:

freeze <- ls() # all objects created after here will be deleted
var <- letters
for (i in var) {
    assign(i, runif(1))
}
df <- data.frame(x1 = a, x2 = b, x3 = c)
rm(list = setdiff(ls(), c(freeze, "df"))) #delete old objects except df

这里的主力是setdiff(),它将返回一个列表,其中包含出现在第一个列表中而不是第二个列表中的项目的列表。在这种情况下,除了df 之外,在freeze 之后创建的所有项目。另外,freeze 也在这里被删除。

【讨论】:

  • 不用说,我是粉丝。 :) 感谢您提到 setdiff()!
  • 啊哈,正是我想要的!简单,优雅,使用基础 R。关于删除 freeze 的部分也非常巧妙。
【解决方案2】:

这应该可行。

source(file="script1.R")
rm(list=ls()[!sapply(mget(ls(),.GlobalEnv), is.data.frame)])

分解:

  1. mget(ls()) 获取全局环境中的所有对象
  2. !sapply(..., is.data.frame 确定哪个不是 data.frame
  3. rm(list=ls()[..] 仅删除不是 data.frames 的对象

【讨论】:

    【解决方案3】:

    我有这样的脚本将结果保存为 RDS 文件,然后在新会话中打开结果(或者,在清除所有内容后)。也就是说,

    a <- 1
    saveRDS(a, file="a.RDS")
    rm(list=ls())
    a <- readRDS("a.RDS")
    a
    ## [1] 1
    

    【讨论】:

      猜你喜欢
      • 2018-10-27
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2019-12-16
      • 2017-08-01
      • 2016-05-28
      • 1970-01-01
      • 2019-03-09
      相关资源
      最近更新 更多