2010-05-26 93 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的一部分。

相關問題