3

これが以前に尋ねられた場合はお詫びします-私は検索機能を使用しました。

変数Xには1〜100のカテゴリがあり、カテゴリごとに行数が可変です(すべて10を超える)。変数Yには、各Xに関連付けられた値があります。Xごとに10 YごとにYのランダムなサブサンプルを抽出するにはどうすればよいですか?目標は、ファイル内のデータの総量を減らすことです(現在、11000行あり、理想的には、ケースを含める/除外するためのバイナリコード化列Zの出力を使用します(Zは各カテゴリXのランダムな10個のYに割り当てられます)。

かなり簡単なはずですよね?

よろしく、KCW

4

3 に答える 3

2

sampleこれは、とave関数の組み合わせで非常に簡単に実行できます。

dfrm$Z <- ave(dfrm$X, dfrm$X, FUN= 
             function(x) sample(c( rep(TRUE,10), rep(FALSE, length(x)-10))) )
dfrm[dfrm$Z , "Y"]

X の各カテゴリ内で、sample は 10 個の TRUE と置換された残りの FALSE を含む論理ベクトルを返します。これは、sample2 番目の長さの引数が指定されていない場合の動作です。FALSEこれにより、Z 列が残るため、 -Zで他のテストを実行できます。の最初の引数aveは基本的に無視され、破棄されます。その唯一の本当の目的は、論理戻り値の構築に使用される長さのベクトルを提供することです。

の関数を作成する場合ave、グループ化変数の 1 つのカテゴリ内で X を 1 回選択するだけで、同じ長さと適切な順序で返されるものを想像すると便利です。グループ化変数は 3 つのドット項目として入力されるため、常に "FUN=" を指定する必要があります。そうしないと、不可解なエラー メッセージが表示されます。

于 2012-09-01T17:02:12.860 に答える
0

Rがどのように機能するかにより、これはおそらく非常に高速なオプションになります。

まず、いくつかのサンプルデータ:

set.seed(1)
dat <- data.frame(x = rep(1:10, times = sample(10:30, 10)))
dat$y <- rnorm(nrow(dat))

次に、zすべての値を持つ変数を作成しますFALSE

dat$z <- FALSE

rleおよびを使用cumsumしてサンプルを把握し、それらをサブセット化し、としてマークを付けますTRUE

RLE = c(1, cumsum(rle(dat$x)$lengths))
dat$z[c(sapply(1:(length(RLE)-1), 
           function(x) sample(RLE[x]:RLE[x+1], 10)))] <- TRUE

ベンチマーク、誰か?

この投稿のサンプルデータを使用して、DWinのソリューション、themelのソリューション、この基本的なサブセット化ソリューション、およびベースRの他の2つのオプションを比較します。

library(rbenchmark)
benchmark(BY = do.call(rbind, 
                       by(dat, dat$x,
                          FUN = function(i) { 
                            i$z <- FALSE; 
                            i[sample(nrow(i), 10), "z"] <- TRUE; 
                            i })), 
          LAPPLY = do.call(rbind, 
                           lapply(split(dat, dat$x), 
                                  FUN = function(i) { 
                                    i$z <- FALSE;
                                    i[sample(nrow(i), 10), "z"] <- TRUE;
                                    i })), 
          SUBSET = { 
            RLE = c(1, cumsum(rle(dat$x)$lengths));
            dat$z <- FALSE; 
            dat$z[c(sapply(1:(length(RLE)-1),
                           function(x) 
                             sample(RLE[x]:RLE[x+1], 10)))] <- TRUE },
          DDPLY = ddply(df, "x" , function(df) {
            pick <- rep(FALSE,nrow(df));
            pick[sample(nrow(df),10)] = TRUE; 
            cbind(df, "z"=pick) 
          }), 
          AVE = { dat$z <- FALSE; 
                  ave(dat$x, dat$x, 
                      FUN=function(x) 
                        sample(c(rep(TRUE, 10), rep(FALSE, length(x)-10))))},
          columns = c("test", "replications", "elapsed", 
                      "relative", "user.self"),
          order = "relative")
#     test replications elapsed   relative user.self
# 3 SUBSET          100   0.044   1.000000     0.044
# 5    AVE          100   0.078   1.772727     0.080
# 2 LAPPLY          100   0.601  13.659091     0.600
# 1     BY          100   0.675  15.340909     0.680
# 4  DDPLY          100   6.016 136.727273     6.008
于 2012-09-01T17:04:39.957 に答える
0

を使用plyrすると、ワンライナーになります。

df <- data.frame(x=rep(1:10, times=1000),y=1:10000)
ddply(df, "x" , function(df) df[sample(nrow(df), 10),])

あなたの論理ベクトルは、私がしたのと同じ原則に従って、もう少し複雑かもしれません

ddply(df, "x" , function(df) { 
    pick <- rep(FALSE,nrow(df)); 
    pick[sample(nrow(df),10)] = TRUE; 
   cbind(df, "z"=pick) 
})

ただし、それを改善できることはかなり確かです。

于 2012-09-01T13:00:19.310 に答える