2011-11-07 15 views
5

特定の列に対して10k個の行を含むデータフレームがあります。重複する値があります。この列にこの値が含まれている行をランダムに1つだけ選択するにはどうしたらいいですか?データフレームで一意に選択します。

答えて

6

あなたの質問は完全ではありませんが、 "重複するクラス"ごとに1つの(ランダムに選択された)行を保持して、データフレーム全体をサブサンプルすると仮定しています。

library(plyr) 
subsampled_data <- ddply(mydata,.(X), 
    function(x) { 
      x[sample(nrow(x),size=1),] 
    }) 

のような何かが(がテストされていません!)動作するはず

+1

OPの(潜在的な)質問のこの解釈は、私が 'df [sample(which df $ X == myVal)、1)]'を提案しようとしていました。 – joran

+1

あなたのスニペットで提案されているmyValがX列に沿って変化するため、これをすべての列の値に適用したい場合は、ベンの提案、Joranのやり方を試しています。 8Sなどなど – Rad

+0

@Rad Benの解決策がそれを処理します。私はしません。私たちはあなたの質問を違った方法で解釈しました。 – joran

6

私の最初の本能は、ベンのエレガントなddplyソリューションのようなものだったでしょう。しかし、今大規模なデータセットがあることを知って、間違いなく速い方法があります。ここでは、多くのユニークな値を持っている場合はより速く、多くの倍となるものです。

RemoveDups <- function(df, column) { 
    inds = sample(1:nrow(df)) 
    df = df[inds, ] 

    dups = duplicated(df[, column]) 
    df = df[!dups, ] 
    inds = inds[!dups] 

    df[sort(inds, index=T)$ix, ] 
} 

は(ここでは多くのユニークな値を持つ)いくつかのデータをシミュレート:

> system.time(ddply(data, 'X1', function(x) x[sample(nrow(x), size=1), ])) 
    user system elapsed 
    3.264 0.921 4.315 
> system.time(RemoveDups(data, 'X1')) 
    user system elapsed 
    0.375 0.025 0.399 

n.row = 10^6 
n.col = 3 

set.seed(12345) 
data = data.frame(matrix(sample(1000, n.row*n.col, replace=T), nrow=n.row)) 

は、2つの方法を比較

+0

エレガント!恐ろしい、ありがとうジョン – Rad

関連する問題