2012-06-27 10 views
6

Rインスタンスを起動時の処女状態に戻すには、そのインスタンスをクリーンアップする必要があります。これまでのところ、私がやっていることです:私はインスタンスをフラッシュする必要がある場合は、起動時にありませんでしたロードされた各パッケージを切り離し[R]で名前空間のインポート順序を決定するには

original_packages <- grep('^package:', search(), value = TRUE) 
original_namespaces <- loadedNamespaces() 

打ち上げで

は、ロードされたパッケージと名前空間を記録:

for (pkg in grep('^package:', search(), value = TRUE)) { 
    if (! pkg %in% original_packages){ 
     detach(pkg, unload=TRUE, force=TRUE, character.only=TRUE) 
    } 
} 

問題は、私は、このようなggplot2として輸入した名前空間の束とパッケージをロードした場合、これらの名前空間がロードされた滞在し、私は、高レベルダウンから、インポートの順序でそれらをアンロードしなければならないということです。私は "名前空間 'x'が 'y'、 'z'によってインポートされるので、アンロードすることはできません"というエラーが出るので、盲目的にアンロードすることはできません。ここで

は再現例です。

original_packages <- grep('^package:', search(), value = TRUE) 
original_namespaces <- loadedNamespaces() 

library(ggplot2) 
library(plyr) 

loadedNamespaces() 

for (pkg in grep('^package:', search(), value = TRUE)) { 
    if (! pkg %in% original_packages){ 
     detach(pkg, unload=TRUE, force=TRUE, character.only=TRUE) 
    } 
} 

for (ns in loadedNamespaces()) { 
    if (! ns %in% original_namespaces){ 
     unloadNamespace(ns) 
    } 
} 

は、名前空間のインポートの階層構造を把握するためにいくつかの方法はありますか?もしそうなら、私はちょうど最後のループを正しく注文することができるはずです...

+4

私は長い時間前にこのメソッドをあきらめました。 AFAIK、 'detach'のドキュメンテーションは、動作保証されていないと言います。唯一の保証された方法は、新鮮なセッションを開始することです。 – Andrie

+0

残念ながら、残念ながら私はrpy2 AFAICTの下で新鮮なセッションを開始できません - これは現在のデザインで永続的なRセッションを持つWebアプリケーション用です。 – Tarek

+1

@アンドリーのコメントにフォローアップ、[このような質問に答えての最後のいくつかのコメント](http://stackoverflow.com/questions/11004018/how-can-a-non-imported-method-in-a-接続されていないパッケージが見つからない場合)は、単にデタッチしてもセッションが元の状態に確実に復元されないという理由の1つになります。 –

答えて

0

@Josh O'Brienが述べたように、名前空間をデタッチまたはアンロードしてクリーンな環境を得ることはできません。

しかし、ここであなたの質問に答えるためには、tools:::dependsOnPkgsを使用して、正しい順序ですべての名前空間をアンロードするための簡単なアプローチです:

## params: originalNamespaces is a list of namespaces you want to keep 
cleanNamespaces <- function(originalNamespaces) { 

    ## which namespaces should be removed? 
    ns <- setdiff(loadedNamespaces(), originalNamespaces) 

    ## get dependency list 
    dep <- unlist(lapply(ns, tools:::dependsOnPkgs)) 

    ## append namespaces to guarantee to fetch namespaces with 
    ## no reverse dependencies 
    ns <- c(dep, ns) 

    ## get namespace names in correct order to unload without errors 
    ns <- names(sort(table(ns), decreasing=TRUE)) 

    ## only unload namespaces which are attached 
    ns <- ns[ns %in% loadedNamespaces()] 

    ## unload namespaces 
    invisible(sapply(ns, unloadNamespace)) 
} 
0

私は確かにハッキーな必要性にハックな解決策を投げました。どのようにこれをより良くするためのアドバイスをいただければ幸いです。特に、グローバルnamespace_depthsオブジェクトの<<-割り当てに満足していません。

original_packages <- grep('^package:', search(), value = TRUE) 
original_namespaces <- loadedNamespaces() 

library(ggplot2) 
library(plyr) 

loadedNamespaces() 

new_packages <- Filter(function(pkg) { ! pkg %in% original_packages }, grep('^package:', search(), value = TRUE)) 

new_namespaces <- Filter(function(ns) { ! ns %in% original_namespaces }, loadedNamespaces()) 

get_imports <- function(ns, depth) { 

    imports <- Filter(function(ns) { ! ns %in% original_namespaces }, names(getNamespaceInfo(ns, 'imports'))) 
    if (length(imports) == 0) { 
     if (is.null(namespace_depths[[ns]]) || namespace_depths[[ns]] < depth){ 
      namespace_depths[[ns]] <<- depth 
     } 
     return() 
    } 
    for (imported_ns in imports){ 
     get_imports(imported_ns, depth + 1) 
    } 
    if (is.null(namespace_depths[[ns]]) || namespace_depths[[ns]] < depth){ 
     namespace_depths[[ns]] <<- depth 
    } 
} 

namespace_depths <- list() 
sapply(new_namespaces, get_imports, 0) 

for (ns in names(namespace_depths)[order(unlist(namespace_depths))]) { 
    if (! ns %in% original_namespaces){ 
     unloadNamespace(ns) 
    } 
} 

for (pkg in new_packages){ 
    detach(pkg, unload=TRUE, force=TRUE, character.only=TRUE) 
} 
+0

FWIW、上の例では、この* still *は、 '.__ S3MethodsTable__()'に登録されている以前に添付されたパッケージ(その場合は 'reorder.factor()' 'gmodels')まだ接続されているパッケージ(その場合は 'stats')です。 –

+0

そのことをありがとう、ジョシュ。幸いなことに、これは私がやっていることには十分であり、sgibbの答えは私のものよりも簡単です。 – Tarek

関連する問題