あなたの質問には、効率的な計算と大量のデータの処理という 2 つの部分があります。
効率的な計算
3,000 万行と 50 列の 5% を含む、より管理しやすいデータ セットがあるm
とします (これは私の 8Gb の約 30% を使用します。メモリが不足するとすべての実行が遅くなるので、このタイプのデータ セットについてお知らせください。情報)。
nrow <- .05 * 30000000
ncol <- 50
m <- matrix(rnorm(nrow * ncol), nrow)
clean
行ごとに外れ値を効率的に削除する関数を作成することもあるでしょう。行単位の標準偏差を効率的に計算する別の関数を使用する可能性があります
rowSD <- function(m) {
## efficiently calculate row-wise SD
## naive: apply(m, 1, sd, na.rm=TRUE)
## update via @BenBolker / http://stackoverflow.com/questions/16046820/change-row-values-to-zero-if-less-than-row-standard-deviation
sqrt(rowSums((m - rowMeans(m, na.rm=TRUE))^2, na.rm=TRUE) / (ncol(m)-1))
}
clean <- function(m) {
## efficiently implement your strategy for identifying outliers
m[abs(m - rowMeans(m)) > 3 * rowSD(m)] <- NA # fast enough
m
}
マトリックスm
の単純な実装にrowSD(m)
は約 56 秒かかりましたが、@BenBolker からの更新には約 1.4 秒かかりました。clean(sd)
約5秒かかります。どちらもデータの複数のコピーを作成し、データを通過させますが、これは理想とはほど遠いものです。
大きなデータ
size のチャンクでデータを処理することを考えてくださいnrow
。2 つのチャンクm1
を消去しm2
た場合、それらを結合して上位の値を保持できます。
sd <- c(rowSD(m1), rowSD(m2))
## if sorted, sd[idx] would be the value that separate high and low
idx <- nrow(result) + nrow(m) - nrow
keep <- sd > sort.int(sd, partial=idx)[idx] # index correct, or off-by-one?
## replace smallest in m1 with largest in m2
m1[!head(keep, nrow(m1)),] <- m2[tail(keep, nrow(m2)),]
scan
行列演算を行っているため、データはすべて数値であり、ファイルをチャンクで読み取ることが適切な入力であるように聞こえます。
conn <- file("myfile", "r")
result <- matrix(0, nrow, ncol)
while (length(x <- scan(con, nmax = nrow * ncol))) {
m <- clean(matrix(x, nrow, ncol, byrow=TRUE))
sd <- c(rowSD(result), rowSD(m))
idx <- nrow(result) + nrow(m) - nrow
keep <- sd > sort.int(sd, partial=idx)[idx]
result[!head(keep, nrow),] <- m[tail(keep, nrow(m)),]
}
close(conn)
result
は、標準偏差が最も高いクリーンな行の目的のコレクションです。