2017-06-26 17 views
3

this questionの拡張として、それ自身が計算の結果である.BY変数を含む計算を実行したいと思います。私が見直した質問では、既存の値にアクセスするだけで、変換や集約はしないキーを使用しています。data.tableで計算された.BYでの操作

この例では、data.tableを利用する関数でバイナリクラシファイアのROCを作成しようとしています(既存のパッケージのROC計算が非常に遅いため)。この場合、変数はカットポイントであり、計算はそのカットポイントでの確率推定に対する真陽性率および偽陽性率です。

私は中間でこれを行うことができますdata.table、しかし私はより効率的な解決策を探しています。

# dummy example 
library(data.table) 
dt <- setDT(get(data(GermanCredit, package='caret')) 
      )[, `:=`(y = as.integer(Class=='Bad'), 
        Class = NULL)] 
model <- glm(y ~ ., family='binomial', data=dt) 
dt[,y_est := predict(model, type='response')] 

#--- Generate ROC with specified # of cutpoints --- 
# level of resolution of ROC curve -- up to uniqueN(y_est) 
res <- 5 

# vector of cutpoints (thresholds for y_est) 
cuts <- dt[,.(thresh=quantile(y_est, probs=0:res/res))] 

# at y_est >= each threshold, how many true positive and false positives? 
roc <- cuts[, .(tpr = dt[y_est>=.BY[[1]],sum(y==1)]/dt[,sum(y==1)], 
        fpr = dt[y_est>=.BY[[1]],sum(y==0)]/dt[,sum(y==0)] 
       ), by=thresh] 

plot(tpr~fpr,data=roc,type='s') # looks right 

enter image description here

しかし、これは動作しません:これは動作します

# this doesn't work, and doesn't have access to the total positives & negatives 
dt[, .(tp=sum((y_est>=.BY[[1]]) & (y==1) ), 
     fp=sum((y_est>=.BY[[1]]) & (y==0) )), 
    keyby=.(thresh= quantile(y_est, probs=0:res/res))] 
# Error in `[.data.table`(dt, , .(tp = sum((y_est >= .BY[[1]]) & (y == 1)), : 
# The items in the 'by' or 'keyby' list are length (6). 
# Each must be same length as rows in x or number of rows returned by i (1000). 

これを行うには、慣用的にdata.table(あるいは少なくとも、より効率的な)方法はありますか?

答えて

2

あなたは非エクイ結合を使用できます。

dt[.(thresh = quantile(y_est, probs=0:res/res)), on = .(y_est >= thresh), 
    .(fp = sum(y == 0), tp = sum(y == 1)), by = .EACHI][, 
    lapply(.SD, function(x) x/x[1]), .SDcols = -"y_est"] 
#   fp   tp 
#1: 1.00000000 1.000000000 
#2: 0.72714286 0.970000000 
#3: 0.46857143 0.906666667 
#4: 0.24142857 0.770000000 
#5: 0.08142857 0.476666667 
#6: 0.00000000 0.003333333 
+0

これはあなたに感謝し、魔法のように素晴らしいです。私は2行目と3行目を理解しています - 'x/x [1]'のトリックは巧妙です。しかし、1行目:私は、非等価結合をgrokしようとしています。これは明らかにnew-ishの機能です(v1.9.8)。 1行目の 'i'で何が起こっているのか理解できますか?自己結合であるため、 'X [Y]'のように 'Y'はありませんか? – C8H10N4O2

+0

ドットは 'data.table'と同じですので、' dt [cuts、... ' – eddi

関連する問題