2011-07-01 12 views
9

私は、RDATAファイル内のオブジェクトのリストを作成し、選択されたオブジェクトのみをロードすることに興味があります。 attach()はうまく動作しないので、名前の競合があるときにこれを行う方法についてはっきりしていません。新しい環境に添付して.rdataファイルの内容を調べることは可能ですか?

1:それをロードせずにRのデータファイルの内容を調べる:この質問は同様の、しかし異なる、一つはその場合listing contents of an R data file without loading

に尋ね、提供される溶液であった:

attach(filename) 
ls(pos = 2) 
detach() 
ファイル内のオブジェクトと地球環境のそれらの間で名前の競合をがある場合

、この警告が表示されます。 The following object(s) are masked _by_ '.GlobalEnv':

私は新しい環境を作成しようとしたが、Iそれに取り付けることはできないようです。例えば 、これは同じエラーを生成します。

lsfile <- function(filename){ 
    tmpEnv <- new.env() 
    evalq(attach(filename), envir = tmpEnv) 
    tmpls <- ls(pos = 2) 
    detach() 
    return(tmpls) 
} 
lsfile(filename) 

は、たぶん私はevalq(またはeval)で物事の混乱を作りました。名前の競合を避けるための他の方法がありますか?

2:オブジェクトにアクセスしたい場合は、名前の競合がない場合は、.rdatファイルのものと作業したり、新しいものにコピーしたりできます。競合がある場合、ファイルの名前空間内のオブジェクトにどのようにアクセスしますか?

たとえば、私のファイルが "sample.rdat"で、オブジェクトがsurveyDataで、surveyDataオブジェクトが既にグローバル環境に存在する場合、file:sample.rdat名前空間から1つにアクセスするにはどうすればよいですか?

私は現在、すべてを一時的な環境にロードし、必要なものをコピーすることでこの問題を解決していますが、これは非効率的です。

+1

r-develに要求があり、完全な.Rdtaファイルを読み込む代わりになるようです。 –

答えて

4

attachへのコールでwarn.conflicts=FALSEを設定すると、警告を抑制することができます。グローバル環境でオブジェクトが1つマスクされている場合は、getを使用して、添付されたデータからオブジェクトを取得できます。

> x <- 1; y <- 2; z <- "foo" 
> save(x, y, z, file="/tmp/foo.RData") 
> ne <- new.env() 
> load(file="/tmp/foo.RData", env=ne) 
> ls(env=ne) 
[1] "x" "y" "z" 
> ne$z 
[1] "foo" 
> 

このアプローチのコストは、あなたが全体のRDATAファイルを読み込むということです---しかし一方で避けられないように思われる:私はちょうどload()env=引数を使用

x <- 1:10 
save(x, file="x.rData") 
#attach("x.rData", pos=2, warn.conflicts=FALSE) 
attach("x.rData", pos=2) 
(x <- 1) 
# [1] 1 
(x <- get("x", pos=2)) 
# [1] 1 2 3 4 5 6 7 8 9 10 
+0

@SimonUrbanekの答えの下に残っているコメントをフォローアップすると、 'attach()'が 'load()'を(Rが変更されていない限り:)呼び出さないと思っているように思えます。このエラーは、検査の不足( 'Rprof()'がそれを明確にする)、および(おそらくディスクキャッシュのための)超高速読み込み時間に起因していました。それでも、これは私の質問の2番目の部分に答えます。 Simonが指摘しているように、1回の使用でロードするのを避ける唯一の方法は、遅延ロード形式に1回の変換を行うことです。 – Iterator

5

とにかく、他の方法ではそのようなファイルの 'コンテンツ'のリストを提供していないようです。

+0

あなたが関心のあるものをグローバルenvにコピーしたら、環境の乱雑さを嫌うなら、 'rm(ne)'を使って新しい環境を破壊することができます。 –

2

@Dirkと@Joshuaに感謝します。

私は出生時を迎えました。コマンド/パッケージforeach(SMPまたはMC)は、地球環境だけを継承するが、矛盾しないような環境を作り出しているようだ。

lsfile <- function(list_files){ 
    aggregate_ls = foreach(ix = 1:length(list_files)) %dopar% { 
     attach(list_files[ix]) 
     tmpls <- ls(pos = 2) 
     return(tmpls) 
    } 
    return(aggregate_ls) 
} 

lsfile("f1.rdat") 
lsfile(dir(pattern = "*rdat")) 

これは私がこれを並列化できるので便利です。これは裸のバージョンであり、より詳細な情報を提供するために修正する予定ですが、これまで無視されていなくても競合を回避する唯一の方法と思われます。

したがって、質問#1は、警告を無視するか(@Joshuaが示唆するように)、または何らかの魔法を使用して解決することができますforeach召喚。

パート2では、オブジェクトを読み込むために、@ Joshuaが適切なアイデアを持っていると思います。「get」が行います。

foreachの魔法は、.noexportオプションを使用しても機能します。しかし、これにはリスクがあります。具体的に除外されないものはすべて地球環境から継承/輸出されます(私はls()を行うことができますが、常にデータセットが添付される可能性があります)。安全のために、これは、名前の競合の危険を避けるために、get()を引き続き使用する必要があることを意味します。サブ環境にロードすると、名前の競合は回避されますが、不要なオブジェクトが読み込まれることはありません。

@ジョシュアの答えは私のforeachの迂回よりはるかに簡単です。この質問がちょうど参照されているので

16

はのは、二つのことを明確にしましょう:あなたはへの選択的なアクセスをしたい場合

  1. attach()は、単にので代わりにload

  2. のそれを使用してもポイントが本当にありませんload()を呼び出しますマスキングができないようにすると、ファイルを新しい環境に簡単に読み込むことが簡単にできます。

    e = local({load("foo.RData"); environment()}) 
    

    ls(e)を使用し、e$xのようなコンテンツにアクセスできます。実際に検索パス上に置いておきたい場合は、まだ環境にattachを使用することができます。

FWIW .RDataファイル(オブジェクトが一つの大きなpairlistに格納されている)は、インデックスを持っていないので、あなたはロードせずに含まれるオブジェクトを一覧表示することができません。便利なアクセスを希望する場合は、lazy-load形式に変換して、インデックスを追加するだけで各オブジェクトを別々にロードできるようにします(Get specific object from Rdata fileを参照)

+0

まずは、あなたを歓迎するコーラスに参加しましょう!次に、 'attach()'が 'load()'を呼び出すという事実は私には驚くべきことです。一つの目標は 'attach()'を使うことでしたが、私が他の答えを受け入れると、 'attach()'が実際よりも速いと思われるテストケースがありました。 'load()'。 OTOH、今私はディスクキャッシングによって誤解されているかもしれないことを理解しています。呪い。何が起こったのかを確認するためには、そのテストケースを再訪する必要があります。 – Iterator

+0

こんにちは、ありがとう - 私はそれに目をつぶっていると思ったので、私はこの記事を意味するわけではありません)に誤情報へのリンクを見た。私はスピードをチェックしなかった、私はちょうどそれのための現在のRコードを見た:P –

関連する問題