4

あるレベルの変数の値を他のすべてのレベルの変数と比較したいデータがあることがよくあります。これを行うためのコードを書くたびに、もっと簡単にできたらいいのにと思います。問題の例を次に示します。

任意のカットのダイヤモンドの平均コストを、ベストカットのダイヤモンドの平均コストと比較したいとします。物事を公平にするために、私は明確さごとに別々にこれを行いたいと思います。

十分なデータがあることを確認しましょう。

> with(diamonds,table(cut,clarity))
           clarity
cut           I1  SI2  SI1  VS2  VS1 VVS2 VVS1   IF
  Fair       210  466  408  261  170   69   17    9
  Good        96 1081 1560  978  648  286  186   71
  Very Good   84 2100 3240 2591 1775 1235  789  268
  Premium    205 2949 3575 3357 1989  870  616  230
  Ideal      146 2598 4282 5071 3589 2606 2047 1212

アイデアにゼロはありません。平均を計算しましょう。

> claritycut<-ddply(diamonds,.(clarity,cut),summarize,price=mean(price))
> claritycut
   clarity       cut    price
1       I1      Fair 3703.533
2       I1      Good 3596.635
3       I1 Very Good 4078.226
4       I1   Premium 3947.332
5       I1     Ideal 4335.726
6      SI2      Fair 5173.916
7      SI2      Good 4580.261
8      SI2 Very Good 4988.688
9      SI2   Premium 5545.937
10     SI2     Ideal 4755.953
...

私が望む最終結果は次のとおりです。

   clarity  variable     ratio
1       I1      Fair 0.8541899
2       I1      Good 0.8295348
3       I1 Very Good 0.9406098
4       I1   Premium 0.9104200
5       I1     Ideal 1.0000000
6      SI2      Fair 1.0878822
7      SI2      Good 0.9630586
8      SI2 Very Good 1.0489356
9      SI2   Premium 1.1661043
10     SI2     Ideal 1.0000000
...

しかし、これをきちんと行う方法がわかりません。この質問の残りのほとんどは、計算の中間ステップである除算に関するものです。

ここで、すべてのカットと理想の相対価格を計算したいと思います。計算の途中で表示されると予想されるデータフレームは次のとおりです。1レベルのカットのみを抽出します。

> claritycutideal <- join(subset(claritycut,cut!="Ideal"),summarize(subset(claritycut,cut=="Ideal"),Ideal=price,clarity))
> print(claritycutideal)
Joining by: clarity
   clarity       cut    price    Ideal
1       I1      Fair 3703.533 4335.726
2       I1      Good 3596.635 4335.726
3       I1 Very Good 4078.226 4335.726
4       I1   Premium 3947.332 4335.726
5      SI2      Fair 5173.916 4755.953
6      SI2      Good 4580.261 4755.953
7      SI2 Very Good 4988.688 4755.953
8      SI2   Premium 5545.937 4755.953
...

これは機能しますが、上記のステートメントを書くのは面倒です。それでも、理想的な名前をもう一度言及して、計算を終了する必要があります。

> mutate(claritycutideal,ratio=price/Ideal)

こんな感じがしたい

> cast(claritycut,clarity~cut)
Using clarity, cut as id variables
  clarity     Fair     Good Very Good  Premium    Ideal
1      I1 3703.533 3596.635  4078.226 3947.332 4335.726
2     SI2 5173.916 4580.261  4988.688 5545.937 4755.953
3     SI1 4208.279 3689.533  3932.391 4455.269 3752.118
4     VS2 4174.724 4262.236  4215.760 4550.331 3284.550
...

計算ですべてのリキャストレベルの名前を知る必要があるため、これは平均計算にはまったく適していません。

リキャストしたいのですが、抽出されたレベルをフィルタリングし、残りをそのままにしておく方法があります。たとえば、次のようになります。

> cast(claritycut,clarity~cut,subset=cut=="Ideal")

これは存在しますが、フィルタリングされていないレベルを保持しません。

それから私はそれを再び溶かす必要があるでしょう、そしてリキャストがある間、再キャストはありません。

誰かがこれを行うための巧妙なトリックを持っていますか?

または、おそらく私はこれを完全に間違った方法で見ています-限界計算は私のためにこれを行いますか?


以下は正確に機能しますが、面倒です。

> valuevars=function(x)x[!names(x)%in%attr(x,"idvars")]
> melt(ddply(cast(claritycut,clarity~cut),.(clarity),
             function(x)valuevars(x)/x$Ideal))
4

3 に答える 3

6

これで十分かどうかはわかりませんが、2つのライナーがあります。

# from your code
claritycut <- ddply(diamonds,.(clarity,cut),summarize,price=mean(price))

# 1 do that work
transform(merge(claritycut, subset(claritycut, cut=="Ideal"), by="clarity"),
  ratio = price.x / price.y)

# 2 another way
ddply(claritycut, .(clarity), 
      function(x) data.frame(cut=x$cut, 
                             rate=x$price / subset(x, cut == "Ideal")$price))

# 3 another way
ddply(claritycut, .(clarity), 
      summarize, cut=cut, rate=price / price[cut == "Ideal"])

そして最後に4)ここにワンライナーバージョンがあります:

ddply(diamonds, .(clarity), 
      function(x) transform(ddply(x, .(cut), 
                                  summarize, rate=mean(price)), 
                            rate=rate/mean(subset(x, cut=="Ideal")$price)))

しかし、複雑すぎます。

于 2011-07-21T04:37:33.147 に答える
2

キャスト後にそれに応じて分割できるレベルがいくつあるかを知る必要はありません2:ncol(x)。それを処理します。ここでの1行の解決策は簡潔ですが、あまり明確ではありません。コードを強制的にエレガントにするのではなく、理解しやすいものにするようにしてください。何かが可愛すぎると、後で複製するのが難しくなることがわかりました。

x <- cast(diamonds, clarity ~ cut + ., mean, value="price")
x <- cbind(x[1],x[2:ncol(x)]/x$Ideal)
x <- melt(x) 

また:

x <- cast(diamonds, clarity ~ cut + ., mean, value="price")
x <- melt(cbind(x[1],x[2:ncol(x)]/x$Ideal)) # The last two as one step
于 2011-07-21T09:02:26.083 に答える
0

これは、dlplyへの式引数で何か面白いことをします。

summarize(do.call(merge,c(by="clarity",
                          dlply(
                                ddply(diamonds,.(clarity,cut),
                                      summarize,meanp=mean(price)),
                                .(ifelse(cut!="Ideal","x","y"))))),
          clarity,cut=cut.x,ratio=meanp.x/meanp.y)

複雑ですが、固定部分を関数にまとめることができるかもしれません。

于 2011-07-21T05:51:20.097 に答える