1

私はRにほとんど慣れていないので、基本的な質問をすると申し訳ありませんが、この「単純な」問題の解決策を見つけることができません。患者のデータベース(大きなもの、2500万行、14列)があるので、いくつかあります。各「id」の行。たとえば、次の構造です。

"id" "birth_date"  "treatment"  "date_treatment"
123   2002-01-01    2            2011-01-03
123   2002-01-01    3            2011-10-03
124   2002-01-01    6            2009-11-07
124   2002-01-01    NA           NA
...   .....         ......       ........ 
1022  2007-01-01    4            2011-01-06

少量のRAMで作業できるようにするには、ffパッケージを使用する必要があるため、すべてのプロセスをff関数にする必要があります。そして、私は知りたいのですが、各単一の「id」について、彼/彼女が治療を受けたときの最小の「年齢」= 2または4です。したがって、各単一のIDでは、一般的なコードでは次のようになります。

if(c(2,4)の処理)then min(date_treatment --birth_date)

私はそれらの最小の「年齢」データとおそらくIDだけを保持したいと思います。

1つの解決策は次のことです。

age_c <- (data$date_treatment - data$birth_date)/365.25;
data$age_c <- age_c;
idx <- ffwhich( data, treatment %in% c(2,4) );
result  <- data[idx,];

これにより、すべてのプロセスがffに保たれ、メモリの問題は発生しませんが、...各IDの最小年齢を取得する方法を見つける必要があります...ffdfdplyはそれを実行できるようです。

age_fun <- function(x){ 
  min_ <- min.ff(x$age_c); 
  data.frame( age = min_);  
}

 result2 <- ffdfdply(x = data,
               split = data$id,
               FUN = function(x) age_fun(x),
               BATCHBYTES = 5000,
               trace=TRUE
 ); 

これには時間がかかり、さまざまなエラーが発生します。

それに対する解決策はありますか?
SASまたはSQLで実行するのは簡単であるというのは一般的な問題ですが、Rで正しい組み合わせが見つかりません。したがって、一般的な質問は次のようになります。

非常に大きなデータセットの変数(行)の同一の値(グループ)の行-列関数を計算する方法???

ありがとう !!

4

1 に答える 1

2

ffdfdplyは質問を解決するために必要な関数ですが、間違って非効率的に使用しています。ffdfdplyを各FUNに取り込むものと考えてください。データの最大数Rを使用すると、RAMに入れることができますが、RAM内の各ID(または、RAMに収まる場合は複数のID)ですべてのデータを取得できます。

したがって、BATCHBYTES 5000の使用はかなり小さいです(実際には5キロバイトのRAMしかありません-私はそうは思いません-90年代からコモドールにRをインストールしましたか?)次に、FUNage_funが間違って書き込まれます。FUNで何が得られるかを確認するには、印刷してください。FUN = function(x){print(head(x)));のように バツ}。FUNでは、RAMにデータを取得するため、min.ffを使用する必要はありません。minで使用できます。

また、joranの注釈にも注意してください。RAMで許可されている場合は、各チャンクで複数のIDを取得します。FUNがsplit-apply-combine戦略を実行するか、FUNでdplyを使用することを確認してください。そして、物事をスピードアップするための別の発言。本当にffdf全体を渡す必要がありますか?関数と分割で使用する列のみが必要です。したがって、ffdfdply(x = data [c( "id"、 "age_c"、 "treatment")]、split = ...)を実行すると、必要のないデータがRAMに取得されます。

簡単に言うと、このようなものでうまくいきます

require(doBy)
result2 <- ffdfdply(
  x = data[c("id","age_c","treatment")], split = data$id,
  FUN = function(x) summaryBy(age_c ~ id, data=subset(x, treatment %in% c(2,4)), FUN=min))

治療2と4の治療を受けていない人も欲しい場合は、このようにしてください。

require(doBy)
result2 <- ffdfdply(
  x = data[c("id","age_c","treatment")], split = data$id,
  FUN = function(x) {
   persons <- unique(x[, "id", drop=FALSE])
   result <- merge(
     persons,
     summaryBy(age_c ~ id, data=subset(x, treatment %in% c(2,4)), FUN=min),
     by.x="id", by.y="id", all.x=TRUE, all.y=FALSE
     )
   result
})
于 2012-11-15T22:31:47.113 に答える