2017-06-20 3 views
0

以下のdata.tableを指定すると、どのようにして目的の結果を得ることができますか? 'grpFreq'列には元のdata.tableの各 'grp'の数が含まれ、 'posCnt'列には各グループの 'val'の正数の数が格納され、 'ratio'列はposCnt/grpFreqです。グループの頻度、条件を満たす値の数、および比率(data.tableのグループ別)

library(data.table) 

DT <- data.table(grp = c(1,2,5,5,5,5,3,4,4,4), val = c(-1,0,1,1,-1,1,1,-1,-1,1)) 
DT 

    grp val 
1: 1 -1 
2: 2 0 
3: 5 1 
4: 5 1 
5: 5 -1 
6: 5 1 
7: 3 1 
8: 4 -1 
9: 4 -1 
10: 4 1 

この望ましい結果へ:

# grp grpFreq posCnt ratio 
# 1  1  0  0 
# 2  1  0  0 
# 3  1  1  1 
# 4  3  1  0.33 
# 5  4  3  0.75 

次の試みは私の道の一部を取得します。まず、「ヴァル」列から、> 0の値の数は、ここでは右端の列(「-1」と「0」の列が必要とされていない)にされています

dcast(DT, grp~val, length) 

    grp -1 0 1 
1: 1 1 0 0 
2: 2 0 1 0 
3: 3 0 0 1 
4: 4 2 0 1 
5: 5 1 0 3 

第二に、これは私を取得します各 'grp'の頻度カウントですが、上記と同じ形式ではありません。

library(dplyr) 
DT %>% 
    group_by(grp) %>% 
    mutate(count = n()) 

    grp val count 
    (dbl) (dbl) (int) 
1  1 -1  1 
2  2  0  1 
3  5  1  4 
4  5  1  4 
5  5 -1  4 
6  5  1  4 
7  3  1  1 
8  4 -1  3 
9  4 -1  3 
10  4  1  3 

どうもありがとう!! data.table

+0

を返します。あなたの 'dplyr'コードの問題は、あなたが' group_by(grp) 'ですが、あなたは' mutate'だけあなたのグループを要約していません。 'mutate'は' grp'の各値のための単一のエンティティではなく、あなたのデータセット内の同じ数の行を返します。そういうわけで、それはあなたが期待したように動作していません。 –

+0

また、 'data.table'でサンプルデータを作成する特定の理由があるかどうかはわかりません。 'dplyr'パッケージの' data.frame() 'や' data_frame() 'と同じように簡単に使うことができます。あなたのサンプルデータを作成するためだけに 'data.table'ライブラリを使う必要があると思う場合には、ちょっと言ってください。 –

+0

こんにちは@StevenMortimer。行方不明のリンクありがとうございました。当時の文法を頭に浮かべることはできませんでしたが、今は意味があります。したがって、各要素の結果はパイプラインの後続の要素で利用できます。私のデータはdata.tableに存在するので、ここで使用します。 –

答えて

1
DT <- data.table(grp = c(1,2,5,5,5,5,3,4,4,4), val = c(-1,0,1,1,-1,1,1,-1,-1,1)) 

DT %>% 
    group_by(grp) %>% 
    summarize(grpFreq = length(grp), 
      posCnt = sum(val > 0)) %>% 
    mutate(ratio = posCnt/grpFreq) 

# A tibble: 5 × 4 
    grp grpFreq posCnt  ratio 
    <dbl> <int> <int>  <dbl> 
1  1  1  0 0.0000000 
2  2  1  0 0.0000000 
3  3  1  1 1.0000000 
4  4  3  1 0.3333333 
5  5  4  3 0.7500000 
+0

こんにちはスティーブン。 dplyrバージョンありがとうございます。 @Imoは最初に回答したので、ソリューションとしてフラグを立てます。ただし、50k行と3k列のデータセットでこれを使用すると同等です。 –

+0

提案された回答の順番は、誰かが時間順に回答したときではなく、アップボトムまたはダウンボートの数によって異なります。 @lmoの15分前に回答しましたが、upvoted回数が少なくなったので、それは下にリストされています。あなたは、ページ上の順序に関係なく、あなたの質問に最もよく答える答えにフラグを立てるべきです。 –

+0

@SteveMortimerヘッドアップありがとう。これらの2つの回答は私の現在の使用と同等です。ネクタイを壊すためだけに年代順を使用しました。それを覚えてお詫びします。今修正されました。 –

2

、あなたが

DT[order(grp), .(grpFreq=.N, posCnt=sum(val > 0), ratio=sum(val > 0)/.N), by=grp] 
1回の呼び出しで

またはより良いチェーンを使用して:=

DT[order(grp), .(grpFreq=.N, posCnt=sum(val > 0)), by=grp][, ratio := posCnt/grpFreq][] 

を行うことができ、それは計算の数を減らすように、第2の方法は、おそらく好ましいです。 :=での割り当てはメモリ効率的です。 2番目の呼び出しの最後の[]は実際には必要ではありませんが、結果を画面に出力するようにdata.tableに指示します。

どちら

は `dplyr`パイプラインの一部として、私はあなたのすべての計算を実行することをお勧め

grp grpFreq posCnt  ratio 
1: 1  1  0 0.0000000 
2: 2  1  0 0.0000000 
3: 3  1  1 1.0000000 
4: 4  3  1 0.3333333 
5: 5  4  3 0.7500000 
+0

こんにちは@Imo。私のコードはこれにも近くなかった!説明をありがとうございます。構文を解読するために、DataCampのチートシートを[link](https://s3.amazonaws)で使用しました。com/assets.datacamp.com/img/blog/data + table + cheat + sheet.pdf) –

関連する問題