2017-09-26 3 views
1

私は、スキューを除いて観測数が等しいビンに分割したいと思うビンに分割したいデータセットを持っています。R - cut2 - 0のための1つのビンと他のすべてのための10の

明確にするために、私は多数のゼロと、> 0個の観測値の比較的少ない数を持っています。

cut2を使用して値を10個のビンに0を含めてビンすると、次のようになります。 X

data.table(DT[, cut2(x, g=10)])[,.N, by=V1] 
     V1 N 
1:  0 100 
2: [ 1, 21) 20 
3: [21, 41) 20 
4: [41, 61) 20 
5: [61, 81) 20 
6: [81,100] 20 

で見ているだけ

library(data.table) 
library(Hmisc) 

DT<-data.table(x=rep(0,100), y=rep(0,100)) 
DT<-rbind(DT, data.table(x=seq(1:100),y=seq(1:100))) 
DT 
     x y 
    1: 0 0 
    2: 0 0 
    3: 0 0 
    4: 0 0 
    5: 0 0 
---   
196: 96 96 
197: 97 97 
198: 98 98 
199: 99 99 
200: 100 100 

だから100個のゼロの存在は、ゼロ上記の観察は、5つのバケットに束ねされている点にビンをシフトしています。私がやりたいのは何

私は、具体的にゼロをフィルタリングし、10個のビンを適用した場合、予想通り、私は次の取得...

data.table(DT[x>0, cut2(x, g=10)])[,.N, by=V1] 
      V1 N 
1: [ 1, 11) 10 
2: [11, 21) 10 
3: [21, 31) 10 
4: [31, 41) 10 
5: [41, 51) 10 
6: [51, 61) 10 
7: [61, 71) 10 
8: [71, 81) 10 
9: [81, 91) 10 
10: [91,100] 10 

は11個のバケツ持っている - ゼロのための1つをと非ゼロの場合は10です。私はもちろんそう

DT[x==0, bin:=cut2(x, g=1)] 
Warning message: 
In min(diff(x.unique)) : no non-missing arguments to min; returning Inf 

DT[x>0, bin:=cut2(x, g=10)] 
DT[, .(min(x), max(x)), by=bin] 
     bin V1 V2 
1:  0 0 0 
2: [ 1, 11) 1 10 
3: [11, 21) 11 20 
4: [21, 31) 21 30 
5: [31, 41) 31 40 
6: [41, 51) 41 50 
7: [51, 61) 51 60 
8: [61, 71) 61 70 
9: [71, 81) 71 80 
10: [81, 91) 81 90 
11: [91,100] 91 100 

のような2回の別々の操作でこれを適用することができますしかし、私はその後、yについて、同じ2つの動作を繰り返す必要があります。私の実際のデータテーブルは約30列であるので、私はそこにいるかどうか疑問に思っています:

  1. 私はこれらの2つの操作を1つの列にまとめて適用できるショートカットですか?
  2. 30個の列のリストに対してこれら2つの操作を適用できるショートカットですか?

私が見ることができる重要なビットは、フィルタの部分です - 分布はすべてゼロに向かって歪んでいますが、各列には異なる数の観測値が含まれ、異なるビンがあります。

何か指摘していただければ幸いです。

デビッド

p.s.うまくいけば、ポストのレイアウトは、コードをカット&ペーストできるようになります。出力を明瞭にするために出力を含めましたが、問題がある場合は教えてください。

EDIT エディの答え@見直し、私のデータに適用した後、私は私が実際に実行しているデータ対に提供したデータに問題があることがわかります。 、主に -

これらは私が次のように結果のこれらの種類を再現するために設定されたテストデータを更新した私のデータにエディのメソッドを使用して実行した結果(名前がマスクされている)...

> data.table(XXX[, cut2(yyy, m = 
sum(yyy > 0)/10)])[, .N, by = V1] 
       V1 N 
1: [ 0, 4) 284 
2: [3891,72337] 264 
3: [1212, 3891) 264 
4: [ 519, 1212) 264 
5: [ 208, 519) 263 
6: [ 49, 101) 267 
7: [ 101, 208) 263 
8: [ 11, 24) 258 
9: [ 24, 49) 263 
10: [ 4, 11) 252 
> XXX[yyy==0, .N,] 
[1] 74 
> XXX[yyy>=0, .N,] 
[1] 2642 

です潜在的な値の範囲を70,000に拡張し、それらを連続してではなくランダムに生成する。また、それらの2700を生成するのではなく、私は

DT<-data.table(x=rep(0,100), y=rep(0,100)) 
DT<-rbind(DT, data.table(x=runif(2600,1,70000),y=runif(2600,1,70000))) 
DT 
data.table(DT[, cut2(x, m = sum(x > 0)/10)])[, .N, by = V1] 

      V1 N 
1: [ 0, 4798) 270 
2: [41289,48407) 270 
3: [11482,18413) 270 
4: [48407,55678) 270 
5: [55678,62157) 270 
6: [33040,41289) 270 
7: [25470,33040) 270 
8: [ 4798,11482) 270 
9: [62157,69983] 270 
10: [18413,25470) 270 

で働いていた100かそこらは、これは10個のバケットの残りの部分にゼロのためのバケツをロールアップしている - 確かにこれは、大規模分布に影響を与えていないが、それはですこのメソッドがわずかに分解しているように見える列の1つ。

テストデータとの間違いをお詫びしますが、このような影響は予期しませんでした。

歓迎されるであろう続行する方法上の任意の考え...

乾杯

エディからのフィードバックの後デビッド

+0

0のビニングとそれ以外の0のビニングを別々に行い、列のforループで実行します。 – eddi

+0

こんにちは@エッディー、確かに - それは私の背中のオプションとして持っていたものですが、私はあなたの提案を見た後にRでいくつかのトリックを学んだので、ありがとうございます。 – Bravid

答えて

1

、これで私自身の実験では、私は、forループを使用することにしました最初にゼロをビニングしてから、別々に非ゼロをビニングします。

DT<-data.table(x=rep(0,100), y=rep(0,100)) 
DT<-rbind(DT, data.table(x=runif(100,1,10000),y=runif(100,1,10000))) 
DT 


cols <- data.table(col_name=c("x","y")) 


for(col in 1:nrow(cols)){ 

    DT[get(cols[col, col_name])==0,(paste(cols[col,col_name],"_bin",sep="")):= cut2(get(cols[col, col_name]),g=1)] 
    DT[get(cols[col, col_name])>0,(paste(cols[col, col_name],"_bin",sep="")):= cut2(get(cols[col, col_name]),g=10)] 

} 

data.table(DT[, cut2(x, m = sum(x > 0)/10)])[, .N, by = V1] 

        V1 N 
1:    0.00 100 
2: [2540.22,4009.79) 10 
3: [4923.05,5736.81) 10 
4: [4009.79,4923.05) 10 
5: [ 910.57,1563.99) 10 
6: [5736.81,6121.23) 10 
7: [ 9.77, 910.57) 10 
8: [9240.77,9957.27] 10 
9: [1563.99,2540.22) 10 
10: [6121.23,7759.80) 10 
11: [7759.80,9240.77) 10 
関連する問題