2017-08-15 17 views
0

のためのパーセンタイルを算出し、私は数値変数の何十もこのdata.table:すべての数値変数

set.seed(1) 
dt <- data.table(id = c("A", "A", "B", "B","C", "C"), 
      var1 = c(1:6), 
      var2 = rnorm(6)) 

> dt 
    id var1  var2 
1: A 1 -0.6264538 
2: A 2 0.1836433 
3: B 3 -0.8356286 
4: B 4 1.5952808 
5: C 5 0.3295078 
6: C 6 -0.8204684 

しかしのようなデータを持っています。キー識別子(id)をそのまま維持しながら、data.tableを使用して、各観測値と各数値変数のパーセンタイルを計算したいと思います。 dplyrで私はこのようにそれを行うことができます:

mutate_if(dt, is.numeric, function(x) { ecdf(x)(x) }) 

    id  var1  var2 
1 A 0.1666667 0.5000000 
2 A 0.3333333 0.6666667 
3 B 0.5000000 0.1666667 
4 B 0.6666667 1.0000000 
5 C 0.8333333 0.8333333 
6 C 1.0000000 0.3333333 

私はまた、元var1var2を含む結果と幸せになります。

このアプローチにはどのような方法が最適でしょうか?

ありがとうございました!

+1

は説明する時間がありませんが、これは、id列なしで何をしたいあなたを与える必要があります: 'DT [、lapply(.SD、関数(x)は関数ecdf(x)は、(X)) 、.SDcols =サプリー(dt、is.numeric)] '。その後、id列を 'cbind'することができます。 – jav

+0

mutate_at(dat、vars(starts_with( "var"))、function(x){ecdf(x)}) 'または' mutate_if(dat、is.numeric、function(x){ecdf )(x)}) ' –

+0

@ jav、結果に' id'を保持する方法はありますか?何らかの理由で元のデータと比較して簡単な結びつきが返ってきます。 –

答えて

2

あなたは、このような個別のデータテーブル内のすべての数値の列のecdfを計算することができます:

dt2 = as.data.table(lapply(dt,function(x){if(is.numeric(x)){ecdf(x)(x)}})) 

結果:あなたはcbindに元dtにこの結果をしたい場合は

> dt2 
     var1  var2 
1: 0.1666667 0.8333333 
2: 0.3333333 0.3333333 
3: 0.5000000 0.6666667 
4: 0.6666667 1.0000000 
5: 0.8333333 0.1666667 
6: 1.0000000 0.5000000 

、あなたpaste0を使用して列名を変更できます。

colnames(dt2) = paste0("centile_",colnames(dt2)) 

結果:

> dt2 
    centile_var1 centile_var2 
1: 0.1666667 0.8333333 
2: 0.3333333 0.3333333 
3: 0.5000000 0.6666667 
4: 0.6666667 1.0000000 
5: 0.8333333 0.1666667 
6: 1.0000000 0.5000000 
+0

ありがとう!あなたの結果には 'id'が含まれていません。単に' cbind'を試みると元のデータとは異なる結果が得られます。結果にそれを保持する方法はありますか? –

+2

最後に 'else.d'を追加するだけです:' as.data.table(lapply(dt、function(x){if(数値)x {ecdf(x)} else x}) ) '。 – lmo

+0

@lmo、そのおかげで、そのトリックでした! –

関連する問題