5

これが私の問題です。20 万行のデータセットがあります。

  • 各行は、被験者に対して実施されたテストに対応しています。
  • 被験者のテスト数は等しくありません。
  • 各テストには日付が付けられています。

各テストにインデックスを割り当てたい。例: 被験者 1 の最初のテストは 1、被験者 1 の 2 番目のテストは 2、被験者 2 の最初のテストは 1 などです。

私の戦略は、一意のサブジェクト ID のリストを取得し、lapply を使用して、一意のサブジェクト ID を使用してデータセットをデータフレームのリストにサブセット化し、各サブジェクトがテストを実行した独自のデータフレームを持つようにすることです。理想的には、各被験者の各データフレームをソートし、各テストにインデックスを割り当てることができます.

ただし、これを 200k x 32 データフレームで実行すると、ラップトップ (i5、Sandy Bridge、4GB RAM) のメモリがすぐに不足してしまいました。

2 つの質問があります。

  1. これを行うより良い方法はありますか?
  2. そうでない場合、メモリ制限を克服する唯一の方法は、一意の SubjectID リストをリストごとに 1000 件の SubjectID などの小さなセットに分割し、データセット全体にラップして、すべての最後にリストを結合することです。次に、パーティションの数を示す整数を指定して SubjectID リストを分割する関数を作成するにはどうすればよいですか。たとえば、BreakPartition(Dataset, 5) は、データセットを 5 つのパーティションに均等に分割します。

ダミーデータを生成するコードは次のとおりです。

UniqueSubjectID <- sapply(1:500, function(i) paste(letters[sample(1:26, 5, replace = TRUE)], collapse =""))
UniqueSubjectID <- subset(UniqueSubjectID, !duplicated(UniqueSubjectID))
Dataset <- data.frame(SubID = sample(sapply(1:500, function(i) paste(letters[sample(1:26, 5, replace = TRUE)], collapse ="")),5000, replace = TRUE))
Dates <- sample(c(dates = format(seq(ISOdate(2010,1,1), by='day', length=365), format='%d.%m.%Y')), 5000, replace = TRUE)
Dataset <- cbind(Dataset, Dates)
4

2 に答える 2

5

分割/ラップリーがメモリを使い果たしていると思います。よりベクトル化されたアプローチを検討する必要があります。サンプルコードのわずかに変更されたバージョンから始めます。

n <- 200000
UniqueSubjectID <- replicate(500, paste(letters[sample(26, 5, replace=TRUE)], collapse =""))
UniqueSubjectID <- unique(UniqueSubjectID)
Dataset <- data.frame(SubID = sample(UniqueSubjectID , n, replace = TRUE))
Dataset$Dates <- sample(c(dates = format(seq(ISOdate(2010,1,1), by='day', length=365), format='%d.%m.%Y')), n, replace = TRUE)

そして、あなたが望むのは、被験者ごとに日付順でテストをカウントするインデックスであると仮定すると、次のことができます。

Dataset <- Dataset[order(Dataset$SubID, Dataset$Dates), ]
ids.rle <- rle(as.character(Dataset$SubID))
Dataset$SubIndex <- unlist(sapply(ids.rle$lengths, function(n) 1:n))

「Dataset」の「SubIndex」列には、被験者ごとに番号が付けられたテストのインデックスが含まれています。これは非常に少量のメモリを必要とし、私の 4GB Core 2 duo ラップトップでは数秒で実行されます。

于 2012-05-16T08:41:30.563 に答える
4

plyrこれはパッケージの仕事のように聞こえます。この方法でインデックスを追加します。

require(plyr)
system.time(new_dat <- ddply(Dataset, .(SubID), function(dum) {
    dum = dum[order(dum$SubID, dum$Dates), ]
    mutate(dum, index = 1:nrow(dum))
  }))

これにより、データセットが ごとにチャンクに分割されSubID、インデックスが追加されます。新しいオブジェクトでは、すべてがSubIDグループ化され、時間順に並べ替えられています。あなたの例は私のマシンで約2秒かかり、ほとんどメモリを使用しませんでした. ddplyデータのサイズと特性にどのようにスケーリングするかはわかりませんが、試してみてください。私はこれが十分に速く動作しないので、間違いなくdata.tableパッケージを見てください. (とりわけ)比較し、いくつかのインスピレーションとして役立つ可能性のある私のブログ投稿。ddplydata.table

于 2012-05-16T08:39:00.517 に答える