2010-05-26 83 views
8

我知道我可以使用ls()和rm()来查看和删除我的环境中存在的对象。有什么方法可以从对象中清除R环境?

但是,在处理“旧”.RData文件时,有时需要选择一个环境作为找到要保留的内容以及省略的内容。

我想要做的是让GUI看起来像接口,让我看到对象,对它们进行排序(例如按大小排序),然后删除我不需要的对象(例如,通过复选框界面)。因为我认为这样的系统目前没有在R中实现,所以存在哪些方式?你用什么来清理旧的.RData文件?

感谢,

塔尔

+2

看看这个相关的问题http://stackoverflow.com/questions/2822532/how-can-i-neatly-clean-my-r-workspace-while-preserving-certain-objects – 2010-05-26 17:07:35

回答

2

您可能想查看RGtk2包。 您可以使用Glade Interface Designer轻松创建界面,然后将所需的任何R命令添加到它。

如果您想要一个很好的起点来“窃取”关于如何使用RGtk2的想法,请安装rattle程序包并运行rattle();。然后看源代码,并开始制作你自己的界面:)

我可能会去看看它,看看我能不能做出简单的事情。

编辑:这是一个快速和脏的代码,你可以玩。最大的问题在于,无论什么原因,rm指令都没有得到执行,但我不知道为什么......我知道它是中央指令,但至少该接口起作用! :d

TODO:

  • rm工作
  • 我把所有的变量在remObjEnv环境。它不应该在当前变量中列出,并且当窗口关闭时应该被删除
  • 该列表将只显示全局环境中的对象,其他环境内的任何内容都不会显示,但这很容易实现
  • 可能还有一些其它的错误我都没有想到的:d

享受

# Our environment 
remObjEnv <<- new.env() 

# Various required libraries 
require("RGtk2") 

remObjEnv$createModel <- function() 
    { 
    # create the array of data and fill it in 
    remObjEnv$objList <- NULL 
    objs <- objects(globalenv()) 

    for (o in objs) 
     remObjEnv$objList[[length(remObjEnv$objList)+1]] <- list(object = o, 
      type = typeof(get(o)), 
      size = object.size(get(o))) 

    # create list store 
    model <- gtkListStoreNew("gchararray", "gchararray", "gint") 

    # add items 
    for (i in 1:length(remObjEnv$objList)) 
     { 
     iter <- model$append()$iter 

     model$set(iter, 
       0, remObjEnv$objList[[i]]$object, 
       1, remObjEnv$objList[[i]]$type, 
       2, remObjEnv$objList[[i]]$size) 
     } 

    return(model) 
    } 

remObjEnv$addColumns <- function(treeview) 
    { 
    colNames <- c("Name", "Type", "Size (bytes)") 

    model <- treeview$getModel() 

    for (n in 1:length(colNames)) 
     { 
     renderer <- gtkCellRendererTextNew() 
     renderer$setData("column", n-1) 
     treeview$insertColumnWithAttributes(-1, colNames[n], renderer, text=n-1) 
     } 
    } 

# Builds the list. 
# I seem to have some problems in correctly build treeviews from glade files 
# so we'll just do it by hand :) 
remObjEnv$buildTreeView <- function() 
    { 
    # create model 
    model <- remObjEnv$createModel() 
    # create tree view 
    remObjEnv$treeview <- gtkTreeViewNewWithModel(model) 

    remObjEnv$treeview$setRulesHint(TRUE) 
    remObjEnv$treeview$getSelection()$setMode("single") 

    remObjEnv$addColumns(remObjEnv$treeview) 
    remObjEnv$vbox$packStart(remObjEnv$treeview, TRUE, TRUE, 0) 
    } 

remObjEnv$delObj <- function(widget, treeview) 
    { 
    model <- treeview$getModel() 
    selection <- treeview$getSelection() 
    selected <- selection$getSelected() 
    if (selected[[1]]) 
     { 
     iter <- selected$iter 
     path <- model$getPath(iter) 
      i <- path$getIndices()[[1]] 
      model$remove(iter) 
     } 

    obj <- as.character(remObjEnv$objList[[i+1]]$object) 
    rm(obj) 
    } 

# The list of the current objects 
remObjEnv$objList <- NULL 

# Create the GUI. 
remObjEnv$window <- gtkWindowNew("toplevel", show = FALSE) 
gtkWindowSetTitle(remObjEnv$window, "R Object Remover") 
gtkWindowSetDefaultSize(remObjEnv$window, 500, 300) 
remObjEnv$vbox <- gtkVBoxNew(FALSE, 5) 
remObjEnv$window$add(remObjEnv$vbox) 

# Build the treeview 
remObjEnv$buildTreeView() 

remObjEnv$button <- gtkButtonNewWithLabel("Delete selected object") 
gSignalConnect(remObjEnv$button, "clicked", remObjEnv$delObj, remObjEnv$treeview) 
remObjEnv$vbox$packStart(remObjEnv$button, TRUE, TRUE, 0) 

remObjEnv$window$showAll() 
+0

谢谢尼科。如果你成功并准备好了一些东西 - 请让我知道([email protected])谢谢! – 2010-05-27 08:10:31

+0

@Tal Galili:我用一段代码更新了我的答案。这一切都是为了你玩! :) – nico 2010-05-27 20:45:50

+0

嗨尼科 - 太好了,谢谢!我目前无法使用它,因为我在使用Gtk2时遇到了问题,但在修复它之后,我会给你的代码运行。最好,Tal – 2010-05-28 06:10:15

1

OS X的图形用户界面确实有这样的事情,这就是所谓的工作区浏览器。非常方便。我也希望有一个界面显示对象之间的会话依赖关系,也就是说,如果我从plot()开始并向后查找所有用来创建对象的对象。这需要解析历史记录。

+0

谢谢你肯 - 这听起来像一个好主意。你有线索怎么做? – 2010-05-26 20:14:43

+1

您可以使用'?browseEnv'浏览任何平台下的工作区。 'ls.str'提供了一个控制台替代方案。 – 2010-05-27 11:38:55

+0

Richie - 谢谢你,这很酷(我知道ls.str,但不是browseEnv)! – 2010-05-27 12:29:16

15

我从来没有创建.RData文件。如果您正在从事可重复的研究(并且您应该!),您应该能够从R文件获取输入数据文件到所有输出。

当您需要很长时间的操作时,缓存它们才有意义。如果经常使用结构,如:

if (file.exists("cache.rdata")) { 
    load("cache.rdata") 
} else { 
    # do stuff ... 
    save(..., file = "cache.rdata") 
} 

这允许你从缓存文件迅速开展工作,当你需要从头开始重新计算你可以删除你的工作目录中的所有文件RDATA。

+0

我不同意。每次加载所有文件,合并它们,准备?我选择一次数据准备,保存到.RData并从'load'进行分析。 – Marek 2010-05-26 21:41:14

+2

嗨哈德利 - 理论上我会采取你的立场,在实践中它并不总是工作。例如,我有项目在哪里可以找到相关的数据框架,我需要几分钟的R处理。在这种情况下,我宁愿去做马雷克写的东西。 – 2010-05-27 08:07:43

+2

缓存与此工作实践完全正交。我已经添加了一个说明以使其更加清晰。 – hadley 2010-05-27 13:18:39

4

基本的解决方案是加载数据,删除不需要的内容并保存为新的干净数据。


另一种方式来处理这种情况是通过加载它自己的环境

sandbox <- new.env() 
load("some_old.RData", sandbox) 

现在你可以看到里面是什么

ls(sandbox) 
sapply(ls(sandbox), function(x) object.size(get(x,sandbox))) 

然后你有几个posibilities控制加载RDATA :

  • 写什么要新RDATA:save(A, B, file="clean.RData", envir=sandbox)
  • 删除不从环境中想要的东西,你想在全球工作空间的变量rm(x, z, u, envir=sandbox)
  • 化妆拷贝和删除​​

我通常做类似的第三种选择的东西。加载我的数据,执行一些检查,转换,将最终数据复制到全局工作空间并删除环境。


你可以随时实现你想要的。所以

  1. 加载数据
    vars <- load("some_old.RData")
  2. 获取大小
    vars_size <- sapply(vars, function(x) object.size(get(x)))
  3. 令他们
    vars <- vars[order(vars_size, decreasing=TRUE)]
    vars_size <- vars_size [order(vars_size, decreasing=TRUE)]
  4. 让对话框(取决于OS,这里是Windows)中
    vars_with_size <- paste(vars,vars_size)
    vars_to_save <- select.list(vars_with_size, multiple=TRUE)
  5. 删除你不想
    rm(vars[!vars_with_size%in%vars_to_save])

为对象大小的漂亮的形式是我使用基于getAnywhere(print.object_size)

pretty_size <- function(x) { 
    ifelse(x >= 1024^3, paste(round(x/1024^3, 1L), "Gb"), 
    ifelse(x >= 1024^2, paste(round(x/1024^2, 1L), "Mb"), 
    ifelse(x >= 1024 , paste(round(x/1024, 1L), "Kb"), 
         paste(x, "bytes") 
    ))) 
} 

然后解决方案4.可以使用paste(vars, pretty_size(vars_size))

+0

谢谢Marek。你的代码有一些有趣的功能和策略。尽管Nico建议可以设计出类似的东西,但我确实希望 - 这似乎更容易处理。再次感谢Tal。 – 2010-05-27 08:12:05

1

它没有复选框删除与,而您所选择的文件(S),然后单击删除。但是,下面的解决方案是很容易实现:

library(gWidgets) 
options(guiToolkit="RGtk2") 

## make data frame with files 
out <- lapply((x <- list.files()), file.info) 
out <- do.call("rbind", out) 
out <- data.frame(name=x, size=as.integer(out$size), ## more attributes? 
        stringsAsFactors=FALSE) 
## set up GUI 
w <- gwindow("Browse directory") 
g <- ggroup(cont=w, horizontal=FALSE) 
tbl <- gtable(out, cont=g, multiple=TRUE) 
size(tbl) <- c(400,400) 
deleteThem <- gbutton("delete", cont=g) 
enabled(deleteThem) <- FALSE 
## add handlers 
addHandlerClicked(tbl, handler=function(h,...) { 
    enabled(deleteThem) <- (length(svalue(h$obj, index=TRUE)) > 0) 
}) 

addHandlerClicked(deleteThem, handler=function(h,...) { 
    inds <- svalue(tbl, index=TRUE) 
    files <- tbl[inds,1] 
    print(files)       # replace with rm? 
}) 
+0

感谢用户.___,我会在我的RGtk2重新开始工作之后尝试这个。最好,Tal – 2010-05-28 06:11:51

+0

嗨,我试过你的代码(guiToolkit =“tcltk”),它部分工作。我可以看到文件表(我实际上想要ls()对象,但没关系) - 但我没有看到删除按钮(它没有足够的空间)。有任何想法吗 ? – 2010-05-28 06:30:34

+0

是的,这是一些错误,我还没有想出如何解决表格部件。几个简单的黑客是:你可以手动调整窗口的大小;移动gtable实例上方的删除按钮,或者使用水平布局(在ggroup中跳过水平= FALSE) - 约翰 – jverzani 2010-05-28 14:35:01

2

一旦你想通了,你要保留什么,你可以使用从包GDATA功能-keep-做什么它的名字一样。

a <- 1 
b <- 2 
library(gdata) 
keep(a, all = TRUE, sure = TRUE) 

有关-all和-sure-选项的详细信息,请参阅help(keep)。

all: whether hidden objects (beginning with a .) should be removed, unless explicitly kept. 
sure: whether to perform the removal, otherwise return names of objects that would have been removed. 

这个函数非常有用,我很惊讶它不是R的一部分。

相关问题