7

私が通常採用しているアプローチよりも、特定のタイプの変数を計算するためのより簡単な方法があるのではないかと思います。

以下の例はおそらくそれを最もよく説明しています。私は2列のデータフレームを持っています(果物と果物が腐っているかどうか)。行ごとに、たとえば、腐った同じカテゴリの果物の割合を追加したいと思います。たとえば、リンゴには4つのエントリがあり、そのうち2つは腐っているので、リンゴの各行は0.5と表示されます。目標値(純粋に例として)は、「望ましい結果」列に含まれています。

私は以前、フルーツ変数で「ddply」コマンドを使用して(関数としてsum / lengthを使用)、新しい3 * 2データフレームを作成することでこの問題に取り組みました。*「merge」コマンドを使用して、これらの値を古いデータフレームにリンクします。 。

これは回り道のように感じます、そして私はこれをするより良い/より速い方法があるかどうか疑問に思いました!理想的には一般的なアプローチであり、パーセンテージの代わりに、たとえばすべての果物が腐っているのか、果物が腐っているのかなどを判断する必要がある場合は、簡単に調整できます。

よろしくお願いします。

W

    Fruit Rotten Desired_Outcome_PercRotten
1   Apple      1                        0.5
2   Apple      1                        0.5
3   Apple      0                        0.5
4   Apple      0                        0.5
5    Pear      1                       0.75
6    Pear      1                       0.75
7    Pear      1                       0.75
8    Pear      0                       0.75
9  Cherry      0                          0
10 Cherry      0                          0
11 Cherry      0                          0

#create example datagram; desired outcome columns are purely inserted as illustrative of target outcomes
Fruit=c(rep("Apple",4),rep("Pear",4),rep("Cherry",3))
Rotten=c(1,1,0,0,1,1,1,0,0,0,0)
Desired_Outcome_PercRotten=c(0.5,0.5,0.5,0.5,0.75,0.75,0.75,0.75,0,0,0)
df=as.data.frame(cbind(Fruit,Rotten,Desired_Outcome_PercRotten))        
df
4

4 に答える 4

11

あなたはちょうどddplyそしてmutate:でこれを行うことができます

# changed summarise to transform on joran's suggestion
# changed transform to mutate on mnel's suggestion :)
ddply(df, .(Fruit), mutate, Perc = sum(Rotten)/length(Rotten))

#     Fruit Rotten Perc
# 1   Apple      1 0.50
# 2   Apple      1 0.50
# 3   Apple      0 0.50
# 4   Apple      0 0.50
# 5  Cherry      0 0.00
# 6  Cherry      0 0.00
# 7  Cherry      0 0.00
# 8    Pear      1 0.75
# 9    Pear      1 0.75
# 10   Pear      1 0.75
# 11   Pear      0 0.75
于 2013-03-17T23:14:48.093 に答える
10

data.table参照により更新されるため、超高速です。それを使うのはどうですか?

library(data.table)

dt=data.table(Fruit,Rotten,Desired_Outcome_PercRotten)

dt[,test:=sum(Rotten)/.N,by="Fruit"]
#dt
#     Fruit Rotten Desired_Outcome_PercRotten test
# 1:  Apple      1                       0.50 0.50
# 2:  Apple      1                       0.50 0.50
# 3:  Apple      0                       0.50 0.50
# 4:  Apple      0                       0.50 0.50
# 5:   Pear      1                       0.75 0.75
# 6:   Pear      1                       0.75 0.75
# 7:   Pear      1                       0.75 0.75
# 8:   Pear      0                       0.75 0.75
# 9: Cherry      0                       0.00 0.00
#10: Cherry      0                       0.00 0.00
#11: Cherry      0                       0.00 0.00
于 2013-03-17T23:16:34.037 に答える
5

ベースRの1つの解決策は、を使用することaveです。

within(df, {
  ## Because of how you've created your data.frame
  ##   Rotten is actually a factor. So, we need to
  ##   convert it to numeric before we can use mean
  Rotten <- as.numeric(as.character(Rotten))
  NewCol <- ave(Rotten, Fruit)
})
    Fruit Rotten Desired_Outcome_PercRotten NewCol
1   Apple      1                        0.5   0.50
2   Apple      1                        0.5   0.50
3   Apple      0                        0.5   0.50
4   Apple      0                        0.5   0.50
5    Pear      1                       0.75   0.75
6    Pear      1                       0.75   0.75
7    Pear      1                       0.75   0.75
8    Pear      0                       0.75   0.75
9  Cherry      0                          0   0.00
10 Cherry      0                          0   0.00

以下:

transform(df, desired = ave(Rotten == 1, Fruit))

で適用されるデフォルトの関数aveはですmean。したがって、ここには含めません。FUN = some-function-hereただし、別のことをしたい場合は、追加して別の関数を指定できます。

于 2013-03-18T04:44:36.000 に答える
2

すでに出ているようaveに、選択したベースR関数を使用して1つのソリューションを追加しましょうaggregate

次の方法で目的のデータを取得できます。

aggregate(as.numeric(as.character(Rotten)) ~ Fruit, df, mean)

mergeただし、後で(またはワンピースで)静止させる必要があります。

merge(df, aggregate(as.numeric(as.character(Rotten)) ~ Fruit, df, mean))
于 2013-03-18T13:24:59.527 に答える