2

私は非常に単純なことに苦労していますが、私は円を描いて回っていて、どこでエラーが発生したのかわかりません。誰かが私に便利な提案をしてくれることを本当に望んでいます。そうすれば、私はもう行き詰まりません!

私の目標:結果が0より大きいdata.frame内のインスタンスのパーセンテージを計算したい。forループでこれを試したが、役に立たなかった。そこで、さらに検索した後、apply関数を使用して、平均、標準偏差、最小/最大などのさまざまなメトリックを計算しました。これはうまく機能しますが、パーセンテージを計算するために、カスタム関数を作成して、これを適用関数に挿入しても、適用関数は機能しません。

これは私のdata.frameの短縮版です:

     tradesList[c(1:5,10:15),c(1,7)]
   Instrument TradeResult.Currency.
1         JPM                    -3
2         JPM                   264
3         JPM                   284
4         JPM                    69
5         JPM                   283
10        JPM                  -294
11        KFT                    -8
12        KFT                   -48
13        KFT                   125
14        KFT                  -150
15        KFT                  -206

このdata.frameを要約したいのですが、たとえば、各商品の平均TradeResultを表示します。

> tapply(tradesList$TradeResult.Currency., tradesList$Instrument, mean)
 JPM  KFT 
42.3 14.6 

ただし、商品ごとにTradeResult>0の行のパーセンテージも計算したいと思います。'which'関数を使用すると、> 0のインスタンスをチェックできますが、applyはこの関数を引数として受け入れません。

> length(which(tradesList$TradeResult.Currency. > 0)) / length(tradesList$TradeResult.Currency.) * 100
[1] 50
> tapply(tradesList$TradeResult.Currency., tradesList$Instrument, (length(which(tradesList$TradeResult.Currency. > 0)) / length(tradesList$TradeResult.Currency.) * 100))
Error in match.fun(FUN) : 
  c("'(length(which(tradesList$TradeResult.Currency. > 0))/length(tradesList$TradeResult.Currency.) * ' is not a function, character or symbol", "'    100)' is not a function, character or symbol")
> 

ヘルプ関数でこのエラーの詳細を検索し、関数を定式化するさまざまな方法(たとえば、角かっこや引用符を使用)を試しましたが、どちらの方法でも同じ結果になりました。

誰かがゼロより大きいインスタンスのパーセンテージを計算する理由を知っていますか?おそらく私は何かが欠けていますか?

よろしくお願いします。

よろしく、

編集: 簡単なコメントをありがとうG. Grothendieck、Gavin Simpson、DWin。高く評価され、非常に役に立ちました!

解決済み: これが私が今持っているものです:

> tmpData <- tradesList[c(1:5,10:15),c(1,7)]
> tmpData
   Instrument TradeResult.Currency.
1         JPM                    -3
2         JPM                   264
3         JPM                   284
4         JPM                    69
5         JPM                   283
10        JPM                  -294
11        KFT                    -8
12        KFT                   -48
13        KFT                   125
14        KFT                  -150
15        KFT                  -206
> 100*    # to get percentages
+ with( tmpData, 
+ tapply( (TradeResult.Currency. > 0) , Instrument, sum)/   # number GT 0
+        tapply( TradeResult.Currency., Instrument, length) ) # total number
     JPM      KFT 
66.66667 20.00000 
> 100 * tapply(tmpData$TradeResult.Currency. > 0, tmpData$Instrument, mean)
     JPM      KFT 
66.66667 20.00000 
> pcentFun <- function(x) {
+     res <- x > 0
+     100 * (sum(res) / length(res))
+ }
> 
> with(tmpData, tapply(TradeResult.Currency., Instrument, pcentFun))
     JPM      KFT 
66.66667 20.00000

再度、感謝します!

よろしく、

4

3 に答える 3

2

これを試して:

100 * tapply(tradesList$TradeResult.Currency. > 0, tradesList$Instrument, mean)

投稿のサンプルデータを使用すると、次のようになります。

  JPM   KFT 
66.67 20.00 

ここではsqldfを使用しています(ドットはSQL演算子でもあるため、RSQLiteドライバーはドットをアンダースコアに変換するため、ドットがあった場所ではアンダースコアを使用します)。

> library(sqldf)
> sqldf("select Instrument, 
+     100 * avg(TradeResult_Currency_ > 0) as '%>0',
+     avg(TradeResult_Currency_) as 'Avg Currency'
+     from tradesList group by Instrument")
  Instrument   %>0 Avg Currency
1        JPM 66.67        100.5
2        KFT 20.00        -57.4

これらの2つは、すでに投稿されているソリューションaggregateを適切に変更することによっても変換できます。aggregate

于 2010-12-05T16:21:46.413 に答える
2

計算を行うための簡単な関数を記述します。

pcentFun <- function(x) {
    res <- x > 0
    100 * (sum(res) / length(res))
}

次に、それを楽器のグループに適用できます。tapply()

> with(tradeList, tapply(TradeResult.Currency, Instrument, pcentFun))
     JPM      KFT 
66.66667 20.00000 

ただしaggregate()、機器名を含む要約が必要な場合は、より便利です。

> with(tradesList, aggregate(TradeResult.Currency, 
+                            by = list(Instrument = Instrument), pcentFun))
  Instrument        x
1        JPM 66.66667
2        KFT 20.00000
于 2010-12-05T16:23:05.337 に答える
1

合計または平均を使用して論理的な結果を処理し、意味のある要約結果を得ることができます。

100*    # to get percentages
with( tradesList, 
tapply( (TradeResult.Currency. > 0) , Instrument, sum)/   # number GT 0
       tapply( TradeResult.Currency., Instrument, length) ) # total number

編集: Gavin が、一般的によく理解されているクラスであるデータフレームを返す回答を提供したことに気付きました。ガボールと私の両方の返信からの値のクラスは、1 次元の配列でした。オブジェクトを c() で囲むことにより、名前付きベクトルに変換できます。これは、連結とベクトル関数への強制を兼ねています。そして、現状では、期待される方法で「[」を使用してrbindingまたはアクセスし、names()から期待される結果を再実行することは完全に受け入れられます。

関数 tapply は、INDEX 引数の次元数を含む配列を返し、テーブル オブジェクトとの行列演算に非常に効果的に組み合わせることができます。2、3、または 4 次元で意味のあるカテゴリ統計を取得するために、合計をカウントで割ったり、カウントを合計で割ったりすることがよくあります。

于 2010-12-05T16:13:31.557 に答える