2011-01-22 16 views
4

私はこのようなタイプのdata.frameのオブジェクトを持っていますが、はるかに大きな:R:data.frame(または他のデータ構造)での高速乗算選択した行

> head(mydf) 
    id1  id2 n 
1 0 1032142 3 
2 0 1072163 1 
3 0 119323 2 

私は、ファイルの列に印刷する必要がありますa1およびa1であり、それぞれn回である。私はそのようなファイルを取得することができるように:

0 1032142 
0 1032142 
0 1032142 
0 1072163 
0 119323 
0 119323 

を(...それは私のデータとそれらを完了するために数日かかる)私は、次の解決方法を試してみましたが、彼らは、明示的なforループを利用し、信じられないほど遅いです:

for (j in 1:(nrow(mydf))) for (i in 1:(mydf[j,"n"])) write.table(mydf[j,c("id1","id2")], file="trials", append=T, row.names= F, col.names=F) 

他の人は、乗算された行で新しいdata.frameを構築しようとしますが、実行するのがさらに遅くなります。

​​

Rの下でこれを解決する最も単純かつ迅速な方法は何ですか?

答えて

6

あなたのデータをサブセット化してみて、一括して保存すると確信しています:

mydf[rep(1:nrow(mydf), mydf$n), ] 

あなたのデータが数値である場合には、行列をされる操作はるかに速い:

mymat <- as.matrix(mydf) 
reps <- as.integer(mydf$n) 
mymat[rep(1:nrow(mymat), reps), ] 

    id1  id2 n 
1 0 1032142 3 
1 0 1032142 3 
1 0 1032142 3 
2 0 1072163 1 
3 0 119323 2 
3 0 119323 2 

元のdata.frameを操作できれば、おそらく上記の行列を扱うことができます。

0

多分あなたは申し込みとシンクを試みることができます。私はapplyが実際にfor-loopsより速いかどうか分からない(tapplyとlapply definatly)。

mydat=data.frame(id1=0,id2=rnorm(5),n=sample(1:10,5)) 

mydat 

sink("test.txt") 
apply(mydat,1,function(x)cat(paste(rep(paste(x[1:2],collapse="\t"),x[3]),"\n"))) 
sink() 

私はあなただけ試行し、ファイルへのすべての行にのn回を書きたい場合は、コードが

+0

私は 'シンク'はコンソール出力をファイルに出力するためのものだと思います。この場合、データフレームをファイルに書き込む 'write.table'がすでにあります。 –

+0

したがってcatの使用。私は疑問に思っていますが、write.table(...、append = T)よりも速く沈むでしょう。 –

1

恐ろしい見えます知っている:

ロードデモデータ:

data <- structure(list(id1 = c(0L, 0L, 0L), 
    id2 = c(1032142L, 1072163L, 119323L), 
    n = c(3L, 1L, 2L)), .Names = c("id1", "id2", "n"), class = "data.frame", row.names = c(NA, -3L)) 

すべての行を書き込むn回 "output.txt":

file = 'output.txt' 
write.table(data[0,], file=file, row.names=FALSE) 
apply(data, 1, function(x) replicate(x[3], write.table(t(x[1:2]), file=file, append=TRUE, col.names=FALSE, row.names=FALSE))) 

私は、これは多くのよりよい書くことができます:)

関連する問題