2017-02-10 19 views
2

私はHmiscパッケージの関数smean.cl.normalを使用しています。平均値と下位および上位CIの3つの値を持つベクトルを返します。 2グループのdata.tableで使用すると、2列6行が得られます。 2つのグループに対応する2つの行と関数の出力、すなわち平均値とCIのそれぞれについて列を分離して結果を得る方法はありますか?data.table:lapply複数列出力を持つ関数

require(Hmisc) 
require(data.table) 

dt = data.table(x = rnorm(100), 
       gr = rep(c('A', 'B'), each = 50)) 

dt[, lapply(.SD, smean.cl.normal), by = gr, .SDcols = "x"] 

出力:

gr   x 
1: A -0.07916335 
2: A -0.33656667 
3: A 0.17823998 
4: B -0.02745333 
5: B -0.32950607 
6: B 0.27459941 

所望の出力:

gr  Mean   Lower   Upper 
1: A -0.07916335 -0.33656667 0.17823998 
2: B -0.02745333 -0.32950607 0.27459941 
+0

おそらくもっと良い方法がありますが、次のように動作します: 'dt2 < - dcast(dt [、lapply(.SD、smean.cl.normal)、by = gr]、gr〜rowid(gr)); setnames(dt2,2,4、c( 'Mean'、 'Lower'、 'Upper')) ' – Jaap

+0

ありがとうございました。はい、私はキャストでそれをやっただけで、私は欠落している 'data.table'に何かがあると思っていました。 – mattek

+1

は、http://stackoverflow.com/questions/27494813/data-table-computing-several-column-at-once –

答えて

5

DT[i,j,by]j引数リストを期待するので、as.listを使用する:

dt[, 
    Reduce(c, lapply(.SD, function(x) as.list(smean.cl.normal(x)))) 
, by = gr, .SDcols = "x"] 

# gr  Mean  Lower  Upper 
# 1: A 0.1032966 -0.1899466 0.3965398 
# 2: B -0.1437617 -0.4261330 0.1386096 

c(L1, L2, L3)はリストがどのように組み合わされているかを示していますので、.SDcolsにはx以上が含まれている場合にReduce(c, List_o_Lists)がトリックを行います。私はdo.call(c, List_o_Lists)も動作するはずだと思います。


コメント

これが理由のカップルのための非常に非効率的です。そのdata.tableがjで名前のリストを取得して好きではない見てverbose=TRUEをオンにします。

、jの結果は、名前のリストです。グループごとに同じ名前を繰り返し作成することは非常に非効率的です。 j = list(...)の場合、グループ化が完了した後で効率を上げるために、すべての名前が検出、削除、戻されます。たとえば、j = transform()を使用すると、そのスピードアップを防ぐことができます(=に変更することを検討してください)。このメッセージは将来警告にアップグレードされる可能性があります。

さらに、グループ最適化バージョンmeanと、結果をビルドするためにおそらく使用できるその他の機能が欠落しています。しかし、これはあなたのユースケースにとって大きな問題ではないかもしれません。


あなただけの、ただ一つの値列にこれを適用している:

dt[, as.list(smean.cl.normal(x)), by = gr] 

で十分に。

+1

を参照してください。 – mattek

関連する問題