Rで非常に大きなデータセットをプロットするにはどうすればよいですか?
箱ひげ図やバイオリン図などを使用したいのですが。すべてのデータをメモリに収めることはできません。これらのプロットを作成するために必要な要約を段階的に読み込んで計算できますか?もしそうなら、どのように?
Rで非常に大きなデータセットをプロットするにはどうすればよいですか?
箱ひげ図やバイオリン図などを使用したいのですが。すべてのデータをメモリに収めることはできません。これらのプロットを作成するために必要な要約を段階的に読み込んで計算できますか?もしそうなら、どのように?
Dmitriの回答に対する私のコメントを補足するものとして、ff
ビッグデータ処理パッケージを使用して分位数を計算する関数:
ffquantile<-function(ffv,qs=c(0,0.25,0.5,0.75,1),...){
stopifnot(all(qs<=1 & qs>=0))
ffsort(ffv,...)->ffvs
j<-(qs*(length(ffv)-1))+1
jf<-floor(j);ceiling(j)->jc
rowSums(matrix(ffvs[c(jf,jc)],length(qs),2))/2
}
これは正確なアルゴリズムであるため、並べ替えを使用します。したがって、時間がかかる場合があります。
問題は、すべてのデータをメモリにロードできないことです。したがって、@ Marekで前述したように、データのサンプリングを行うことができます。このような巨大なデータセットでは、データの1%しか取得しなくても、基本的に同じ結果が得られます。バイオリン図の場合、これにより密度の適切な推定値が得られます。分位数の漸進的な計算は不可能ですが、これは非常に適切な近似を与えるはずです。これは、@aixが提供したリンクで説明されている「ランダム化された方法」と本質的に同じです。
R以外の日付をサブセット化できない場合は、接続をと組み合わせて使用してサブセット化できますsample()
。次の関数は、データフレームが大きくなりすぎたときにテキスト形式でデータフレームからデータをサンプリングするために使用するものです。接続を少し試してみると、これをsocketConnectionなどに簡単に変換して、サーバーやデータベースなどから読み取ることができます。正しいモードで接続を開いていることを確認してください。
簡単な.csvファイルを取得し、次の関数でデータの一部pをサンプリングします。
sample.df <- function(f,n=10000,split=",",p=0.1){
con <- file(f,open="rt",)
on.exit(close(con,type="rt"))
y <- data.frame()
#read header
x <- character(0)
while(length(x)==0){
x <- strsplit(readLines(con,n=1),split)[[1]]
}
Names <- x
#read and process data
repeat{
x <- tryCatch(read.table(con,nrows=n,sep=split),error = function(e) NULL )
if(is.null(x)) {break}
names(x) <- Names
nn <- nrow(x)
id <- sample(1:nn,round(nn*p))
y <- rbind(y,x[id,])
}
rownames(y) <- NULL
return(y)
}
使用例:
#Make a file
Df <- data.frame(
X1=1:10000,
X2=1:10000,
X3=rep(letters[1:10],1000)
)
write.csv(Df,file="test.txt",row.names=F,quote=F)
# n is number of lines to be read at once, p is the fraction to sample
DF2 <- sample.df("test.txt",n=1000,p=0.2)
str(DF2)
#clean up
unlink("test.txt")
箱ひげ図に必要なのは、分位数、「ひげ」の極値、および外れ値(表示されている場合)だけです。これらはすべて簡単に事前計算されます。関数を見てくださいboxplot.stats
。
RSQLite、SQLiteDF、RODBC、およびbiglmパッケージも確認する必要があります。大規模なデータセットの場合、データをデータベースに保存し、断片のみをRにプルするのに役立ちます。データベースは並べ替えも実行でき、並べ替えられたデータの分位数の計算ははるかに簡単です(次に、分位数を使用してプロットを実行します)。 。
非常に大きなデータセットで散布図と同等の処理を行うためのhexbinパッケージ(bioconductor)もあります(おそらく、データのサンプルを使用したいが、大きなサンプルで機能します)。
データをデータベースに入れ、SQLを使用して分位数を計算できます。参照:http ://forge.mysql.com/tools/tool.php?id = 149
これは興味深い問題です。
箱ひげ図には分位数が必要です。非常に大きなデータセットで分位数を計算するのは難しいです。
あなたのケースでうまくいくかもしれないし、うまくいかないかもしれない最も簡単な解決策は、最初にデータをダウンサンプリングし、サンプルのプロットを作成することです。つまり、一度に多数のレコードを読み取り、それらのサブセットをメモリに保持します(決定論的またはランダムに選択します)。最後に、メモリに保持されているデータに基づいてプロットを作成します。繰り返しますが、これが実行可能かどうかは、データのプロパティに大きく依存します。
あるいは、「オンライン」方式で分位数を経済的かつ近似的に計算できるアルゴリズムが存在します。つまり、一度に1つの観測値が表示され、各観測値は1回だけ表示されます。このようなアルゴリズムの経験は限られていますが、すぐに利用できるRの実装は見たことがありません。
次のペーパーでは、いくつかの関連するアルゴリズムの概要を示します。ストリーム上の分位数。
データの管理可能なサンプルからプロットを作成できます。たとえば、ランダムに選択された10%の行のみを使用する場合、このサンプルの箱ひげ図は、すべてのデータの箱ひげ図と異ならないはずです。
データがデータベース上にある場合は、ランダムフラグを作成できます(ほとんどすべてのデータベースエンジンに何らかの乱数ジェネレーターがあることを私は知っています)。
2つ目は、データセットのサイズです。箱ひげ図の場合、値変数とグループ変数の2つの列が必要です。この例:
N <- 1e6
x <- rnorm(N)
b <- sapply(1:100, function(i) paste(sample(letters,40,TRUE),collapse=""))
g <- factor(sample(b,N,TRUE))
boxplot(x~g)
100MBのRAMが必要です。その場合N=1e7
、1GB未満のRAMを使用します(これは最新のマシンでも管理可能です)。
disk.frame
おそらく、プロットを実行する前に、最初にデータを要約するために使用することを考えることができますか?