2012-06-27 9 views
6

は、私はこの1つdata.tableでグループ化する:1列以上の結果を取得するには?

library(data.table) 

a <- structure(list(PERMNO = c(10006L, 10006L, 10015L, 10015L, 20000L, 20000L), 
        SHROUT = c(1427L, 1427L, 1000L, 1001L, 200L, 200L), 
        PRC = c(6.5, 6.125, 0.75, 0.5, 3, 4), 
        RET = c(0.005, -0.005, -0.001, 0.05, -0.002, 0.0031)), 
        .Names = c("PERMNO", "SHROUT", "PRC", "RET"), 
       class = c("data.table", "data.frame"), row.names = c(NA, -6L)) 

setkey(a,PERMNO) 

ようdata.tableオブジェクトを持っていると私はPERMNOにより、計算の数を実行する必要があるが、ここでは、この例では、彼らは唯一の2あるはずましょう:生産

mktcap <- a[ , tail(SHROUT,n=1)*tail(PRC,n=1),by=PERMNO] 
sqret <- a[, sum(RET^2),by=PERMNO] 

> mktcap 
    PERMNO  V1 
[1,] 10006 8740.375 
[2,] 10015 500.500 
[3,] 20000 800.000 

> sqret 
    PERMNO  V1 
[1,] 10006 5.000e-05 
[2,] 10015 2.501e-03 
[3,] 20000 1.361e-05 

2つの機能を1つに組み合わせて、マトリックス(またはdata.table、data)を生成したいと考えています。最初のフレームはPERMNOであり、2番目のフレームはmktcapで、3番目のフレームはsqrtです。

このグループ化機能(つまりvariable[ , function(), by= ])は、2つの列、つまりキーと結果の2つの列でのみ結果を生成するように見えるという問題があります。

これは私が欲しいものを生産する私の試み(多くの1)である。

 PERMNO   V1 
[1,] 10006 8.740375e+03 
[2,] 10006 5.000000e-05 
[3,] 10015 5.005000e+02 
[4,] 10015 2.501000e-03 
[5,] 20000 8.000000e+02 
[6,] 20000 1.361000e-05 

を生成

comb.fun <- function(datai) { 
    mktcap <- as.matrix(tail(datai[,1],n=1)*tail(datai[,2],n=1),ncol=1) 
    sqret <- as.matrix(sum(datai[,3]^2),ncol=1) 
    return(c(mktcap,sqret)) 
} 

myresults <- a[, comb.fun(cbind(SHROUT,PRC,RET)), by=PERMNO] 

は(結果がすべてありますが、それらは一つの列に強制されました) 。私が試しても、2つ以上の列(または複数の結果列)を持つ行列を返すようにグループ化することはできません。

data.tableにグループ化した結果の列を2つ以上取得することはできますか?

+0

+1し、「マクロの明確な説明を誘発するためのMatthew Dowleの表現ありがとう。 –

答えて

4

回答は、?data.tableヘルプファイルの優れたサンプルセクションにあります(いくつかの要約統計情報を収集するためにlist()を使用しています)。 (それは、下から約20行上がっています)。

out <- a[ , list(mktcap = tail(SHROUT,n=1)*tail(PRC,n=1), 
       sqret = sum(RET^2)), 
     by=PERMNO] 

out 
# PERMNO mktcap  sqret 
# 1: 10006 8740.375 5.000e-05 
# 2: 10015 500.500 2.501e-03 
# 3: 20000 800.000 1.361e-05 

編集:以下のコメントで

、マシューDowleはx[i,j,by]などの呼び出しでj引数がぎこちなく長くなってきているコードをクリーンアップするための簡単な方法を説明します。上記の呼び出しの彼の提案を実装

、あなたの代わりに行うことができます:

## 1) Use quote() to make an expression object out of the statement passed to j 
mm <- quote(list(mktcap = tail(SHROUT,n=1)*tail(PRC,n=1), 
       sqret = sum(RET^2))) 

## 2) Use eval() to evaluate it as if it had been typed directly in the call 
a[ , eval(mm), by=PERMNO] 
# PERMNO mktcap  sqret 
# 1: 10006 8740.375 5.000e-05 
# 2: 10015 500.500 2.501e-03 
# 3: 20000 800.000 1.361e-05 
+0

これは素晴らしいですが、私はlist(function())を持つことができますか?私が尋ねた例は、私がしなければならないものの非常に単純化されたバージョンなので、私はそれを尋ねます。私は5つの結果を返す関数を持っていますが、計算は私が提供したもののような1行の計算ではありません。 – Vivi

+0

あなたは 'a [、{r < - range(PRC); by [PERMNO] 'またはa [、{setNames(as.list(range)(PRC))、c(" min "、" max " ))}、by = PERMNO] '? –

+0

ハ!私はあなたの答えを適合させ、 'out < - a [、list(mkk = mktcap(SHROUT、PRC)、sqret = sum(RET^2))、by = PERMNO]' 'mktcap'は関数です。私はそれに満足していましたが、あなたのコメントも役に立つと思います(私はRで新しいです)。ねえ、ありがとう! – Vivi

1

方法についてはうまく再現性例えば

comb.fun <- function(a) { 
mktcap <- a[ , tail(SHROUT,n=1)*tail(PRC,n=1),by=PERMNO] 
sqret <- a[, sum(RET^2),by=PERMNO] 

return(merge(mktcap,sqret)) 
} 
+0

私の問題私はグループ内にグループを持っているということです。あなたのケースはうまくいきますが、上のレベルのグループ化に行くと、再び2列に変換されます... – Vivi

+0

そして、 'by'クエリは2つの' by'クエリよりはるかに効率的です。 –

+0

最後のいくつかのマイナーなバグは難しいと証明していますが、うまくいけば1.8.1がすぐにCRANに載るはずです... –

関連する問題