1

特定の変数の境界値に基づいてデータフレームを分割し、境界の両側で何かを計算して、行列(できればデータフレーム)を出力しようとしています。以下のコード例:

set.seed(1)
tdata <- data.frame(a1=rnorm(100, mean=5, sd=2), a2=rep(0:1, length.out=100))
tall <- sapply(1:9, function(x) {
  d <- split(tdata, tdata$a1 <= x)
  sapply(d, function (y) {
    1 - max(table(y$a2)/nrow(y))
  })
})

私の結果:

> allErr
           [,1]      [,2]      [,3]      [,4]      [,5]      [,6]      [,7]
FALSE 0.4949495 0.4895833 0.4943820 0.4933333 0.4444444 0.4411765 0.3333333
TRUE  0.0000000 0.2500000 0.4545455 0.4800000 0.4347826 0.4696970 0.4705882
      [,8] [,9]
FALSE  0.5  0.5
TRUE   0.5  0.5

私の連続変数はtdata$a1であり、からの境界値を使用してデータフレームを毎回2に分割し、分割の各部分に対して1:9計算を実行してa2、それを返したいと考えています。

ここでの私の質問:エレガンス(plyr解決策を検討しましたが、最初のsapplyの使用を避けられません)およびさらに重要なことに、私が気付いていない可能性のある他のR関数の正しい使用法の観点からこれを行うための最良の方法は何ですか?また、私のソリューションは、現在持っているデータフレーム(約10000行)よりもはるかに大きなデータフレームではうまくスケーリングできないのではないかと心配しています。

4

2 に答える 2

3

これほどエレガントなものは思い浮かびませんが、この変更により、データフレーム全体ではなく、インデックスベクトルを分割することで、ソリューションのスケーリングがわずかに向上する可能性があります。

set.seed(1)
tdata <- data.frame(a1=rnorm(100, mean=5, sd=2), a2=rep(0:1, length.out=100))
tall <- sapply(1:9, function(x) {
         d <- split(seq_along(tdata$a2), tdata$a1 <= x)
         sapply(d, function (y) {
          1 - max(table(tdata$a2[y])/length(y))
         })
        })

このおもちゃの例のパフォーマンスの向上はかなり小さいです。おそらく、データフレームに2つの列しかないためです。実際のデータフレームにさらに多くの列がある場合は、インデックスベクトルを分割することでより多くのメリットが得られます。

于 2011-05-29T21:44:40.683 に答える
1

また、エレガンスについてはわかりませんが、内部関数をとしてfun0a、'split-lapply'パターンをとして分割するとtsplit、反復全体が次のようになります。

fun0a <- function(x, ...)
    1 - max(table(x) / length(x))
tsplit <- function(thresh, x, splt, fun, ...)
    lapply(split(x, splt <= thresh), fun, ...)
sapply(1:9, tsplit, data$a2, tdata$a1, fun0a)

lapplyこれは、代わりに内部を使用sapplyし、インデックスまたはデータフレーム全体を介してではなく、データの単一列を直接分割します。tsplit外側のsapplyは、同様の状況で再利用されます。たとえば、内側の関数が実際にデータフレームに依存している場合は、値の代わりにインデックス(外側のsapplyで1回計算)を渡します。

fun0b <- function(i, df, ...)
    1 - max(table(df[i,"a2"]) / length(i))
with(tdata,
     sapply(1:9, tsplit, seq_along(a1), a1, fun0b, tdata))

tsplitとして実装するtapplyことができます

tsplit <- function(thresh, x, splt, fun, ...)
    tapply(x, splt <= thresh, fun, ...)
于 2011-05-30T02:00:56.963 に答える