2012-12-28 24 views
5

フラットファイルの形式で一定のデータストリームを読み込んでいるRscriptがあります。別のスクリプトがこのフラットファイルをピックアップし、解析と処理を行い、その結果をdata.frameとしてRDS形式で保存します。その後、眠り、そのプロセスを繰り返す。第... n番目の反復で既存のデータフレーム(RDS)に新しいデータを追加R

saveRDS(tmp.df, file="H:/Documents/tweet.df.rds") #saving the data.frame 

、私は、コードは、新しい行が前の反復以降フラット・ファイルに追加し、処理しています。ただし、デルタラインを永久データフレームに追加するには、それを読み込んで追加してから元に上書きして保存する必要があります。

df2 <- readRDS("H:/Documents/tweet.df.rds") #read in permanent      
tmp.df2 <- rbind(df2, tmp.df) #append new to existing 
saveRDS(tmp.df2, file="H:/Documents/tweet.df.rds") #save it 
rm(df2) #housecleaning 
rm(tmp.df2) #housecleaning 

このアプローチは、RDSが読み取り/書き込み用に開いているときはいつでも、そのファイルに触れたい別のプロセスが待機する必要があるため、危険です。ベースファイルが大きくなると、リスクが増加します。

appendRDS(私は文字通りそうではないことを知っています)私は、ファイルに保存された単一データフレームの反復更新を実現できますか?完全置換ではなく追加を使用しますか?

+0

まず、あなたは悪いことをしていると思います。以前のデータを上書きして、以前のバージョンを効果的に削除します。つまり、既存のドキュメントに追加できるwrite.tableを使用してテキスト形式(CSVなど)でデータを保存するだけではどうですか? –

+0

私は実際には、前のデータのコピーを最新のレコードに上書きしています。うまくいけば、古いものを読み、新しいものを追加し、古いものと古いものを上書きする、プロセスの2番目のブロックがうまくいくことを望みます。 これで、write.tableのappendオプションが表示されます。私はそれが処理のオーバーヘッドを増加させると思ったので、非ネイティブフォーマットから離れていました。しかし、より良い安定性のために、そのステップで少し非効率的な取引をしても問題ありません。 –

+0

?serializeでいくつかの魔法を使って追加機能を作成できるのだろうかと思います。 –

答えて

2

私は、接続を使用してプロセスを保護し、次のプロセスが引き継ぐ前に開閉することができると思います。

con <- file("tmp.rds") 
open(con) 
df <- readRDS(con) 
df.new <- rbind(df,df) 
saveRDS(df.new, con) 
close(con) 

更新:

あなたは、ファイルへの接続が開いているかどうかをテストし、同時実行の問題を抱えている場合は少し待つためにそれを伝えることができます。

while(is.Open(con)) { # untested but something of this nature should work 
sys.Sleep(2) 
} 
+0

ありがとうございました。それは同じスクリプト内で動作するように見えます。これは、別のスクリプト(別のプロセス)が同じRDSに同時にアクセスしていた場合、それを保護するのに役立ちますか?同時実行性に関する私の唯一の経験は、データベースではなく、ファイルであることがうれしいです。 –

+0

@ Brandon-Bertselsen Worked!( ":/Documents/tweet.df.rds H") \t一方(いるisOpen(CON)){ \t \t Sys.sleep(2) \t} \tオープン(CON - '#PASS1 CON <ファイル)、 "WB" \t saveRDS(tmp.df、CON) \t近い(CON、タイプ= "RW") #Pass N CON < - ファイル( "H:/Documents/tweet.df.rds") \t一方(いるisOpen(CON)){ \t \t Sys.sleep(2) \t} \tオープン(CON、 "RB") \t DF2 < - readRDS(CON) \t近い(CON、タイプ= "RW") \t tmp.df2 < - rbind(DF2、tmp.df) \t \t CON < - ファイル( "H:/Documents/tweet.df.rds") \t一方(いるisOpen(CON)){ \t \t Sys.sleep(2) \t} \t(CON、 "WB")オープン \t saveRDS(tmp.df2、con) \t閉じる(con、type = "rw") ' オープン/しかし、私はそれで大丈夫です。 –

1

ディレクトリで番号RDSの一連のファイルを使用しての代わりに、単一のRDSをファイルに何か問題はありますか?データフレームは単純に列のリストなので、ファイル全体を書き直すことなくデータフレームにRDSファイルを追加することはできないと考えられます。したがって、おそらくそれらは一度に1列ずつ直列化されるため、最後の列のみが終了しますファイルの終わり近く。

RDSファイルから一貫性のないデータを読み込むリスクを最小限に抑えたい場合は、そのファイルを読み込み、追加操作を実行してから一時ファイルに書き込んで、名前を変更します完成したら元の名前にファイルします。少なくともリスクの期間はファイルのサイズに依存しません。ファイル名を既存の名前に変更するときに、さまざまなファイルシステムによってどのようなアトミック性が保証されているかに精通していませんが、おそらくsaveRDSの時間よりも優れています。

+0

興味深い考え。読み込まれたすべてのRDSファイルを取得するには少し犠牲になります。その後、ドロップ/リネームを行うためにOSに達する。賢い、しかし私の忍耐を超えて;)。 –

+0

一時ファイルに書き込み、名前を変更する 'saveRDS'のドロップイン置換として機能する関数を書くことができます。 –

関連する問題