2015-10-13 11 views
5

私は、私の研究室で一定の基準の合格率を計算する関数の検証に取り組んでいます。この背後にある数学は非常に単純です。いくつかの合格または不合格のテストがあれば、何%が合格したのですか。データはP1(最初のテストに合格)、F1(最初のテストに失敗した)のいずれかである値の列として提供されるdplyr :: mutateはx/y = NAを与え、要約はx/y =実数を返します

P2又はF2(それぞれ、第二の試験に合格したか失敗しました)。私は全体的な合格率の計算(第1回目と第2回目の試行)と第1回目のテストと第2回目のテストの孤立した計算に役立つ関数passRateを書きました。

検証のためのパラメータを設定した品質スペシャリストが、以下のtest_vector関数を使用して、ベクトルに変換する合格と不合格のカウントの一覧を示しました。

Passデータフレームの3番目の行に到達するまでは、品質に関する専門家の合格/不合格のカウントが含まれていました。代わりに、100%の第二の試験合格率を返すので、それはNAを返します...しかし、私はmutate

library(dplyr) 

Pass <- structure(list(P1 = c(2L, 0L, 10L), 
         F1 = c(0L, 2L, 0L), 
         P2 = c(0L, 3L, 2L), 
         F2 = c(0L, 2L, 0L), 
         id = 1:3), 
        .Names = c("P1", "F1", "P2", "F2", "id"), 
        class = c("tbl_df", "data.frame"), 
        row.names = c(NA, -3L)) 

を使用したときのみ、だからここに私はmutateでやったことに似て何かがあります。

Pass %>% 
    group_by(id) %>% 
    mutate(pass_rate = (P1 + P2)/(P1 + P2 + F1 + F2) * 100, 
     pass_rate1 = P1/(P1 + F1) * 100, 
     pass_rate2 = P2/(P2 + F2) * 100) 

Source: local data frame [3 x 8] 
Groups: id [3] 

    P1 F1 P2 F2 id pass_rate pass_rate1 pass_rate2 
    (int) (int) (int) (int) (int)  (dbl)  (dbl)  (dbl) 
1  2  0  0  0  1 100.00000  100   NA 
2  0  2  3  2  2 42.85714   0   60 
3 10  0  3  1  3 100.00000  100   NA 

私はsummarise

Pass %>% 
    group_by(id) %>% 
    summarise(pass_rate = (P1 + P2)/(P1 + P2 + F1 + F2) * 100, 
      pass_rate1 = P1/(P1 + F1) * 100, 
      pass_rate2 = P2/(P2 + F2) * 100) 

Source: local data frame [3 x 4] 

    id pass_rate pass_rate1 pass_rate2 
    (int)  (dbl)  (dbl)  (dbl) 
1  1 100.00000  100   NA 
2  2 42.85714   0   60 
3  3 100.00000  100  100 

を使用する場合に比較私は、これらが同じ結果を返すことが期待されるだろう。私の推測では、n個のグループ行が結果としてn行にマップされていると仮定しているため、mutateはどこかで問題が発生しています(nを計算すると混乱しますか?)、summariseは開始行の数に関係なく

この動作の背後にある仕組みは誰にも分かりますか?

+3

これは本当に複雑な例です。バグのようなもの(あなたのタイトルの中のもの)が何であるかを簡単に示していますか?ここに典型的なリファレンスがあります:[mcve] – Frank

+0

あなたはそうです、私はそれをデコンボルーションしようと多くの時間を費やしていませんでした。私はすべての余分な関数なしで結果を直接計算するコードを入れました。 – Benjamin

+4

バグのようです: 'Pass < - data.frame(P2 = c(0,3,2)、F2 = c(0,2,0)、id = 1:3); %>%group_by(id)%>%mutate(pass2 = P2 /(P2 + F2)) 'を渡します。 3列目にNAが存在しないはずです – jeremycg

答えて

3

dplyrplyrの間にいくつかの干渉があるようです。私は別の不均衡なデータセットで同じ問題を抱えていたので(グルーピングが必要でした)、ちょうどの3番目のグループが誤ってNAに誤っていました!それで私は家であなたの事例を再現しました。まず、

の後

私はあなたの結果を正確に得ました。それから、パッケージplyrがロードされた私自身のスクリプトを実行しました。 dplyrの後にplyrをロードしないように警告した後、の第3のグループのNAもなくなり、あなたの例も正しく計算されました!ここに私がやったことです(私はNAが第三のグループに残っているかどうかを確認するために1つのより多くの行を追加):

> Pass <- structure(list(P1 = c(2L, 0L, 10L,8L), 
+      F1 = c(0L, 2L, 0L, 4L), 
+      P2 = c(0L, 3L, 2L, 2L), 
+      F2 = c(0L, 2L, 0L, 1L), 
+      id = 1:4), 
+     .Names = c("P1", "F1", "P2", "F2", "id"), 
+     class = c("tbl_df", "data.frame"), 
+     row.names = c(NA, -4L)) 
> Pass %>% 
+  group_by(id) %>% 
+  mutate(pass_rate = (P1 + P2)/(P1 + P2 + F1 + F2) * 100, 
+   pass_rate1 = P1/(P1 + F1) * 100, 
+   pass_rate2 = P2/(P2 + F2) * 100) 
Source: local data frame [4 x 8] 
Groups: id [4] 

P1 F1 P2 F2 id pass_rate pass_rate1 pass_rate2 
(int) (int) (int) (int) (int)  (dbl)  (dbl)  (dbl) 
1  2  0  0  0  1 100.00000 100.00000   NA 
2  0  2  3  2  2 42.85714 0.00000 60.00000 
3 10  0  2  0  3 100.00000 100.00000   NA 
4  8  4  2  1  4 66.66667 66.66667 66.66667 

それから私はやった:

> library("plyr", lib.loc="~/R/x86_64-pc-linux-gnu-library/3.2") 
> Pass %>% 
+  group_by(id) %>% 
+  mutate(pass_rate = (P1 + P2)/(P1 + P2 + F1 + F2) * 100, 
+   pass_rate1 = P1/(P1 + F1) * 100, 
+   pass_rate2 = P2/(P2 + F2) * 100) 
Source: local data frame [4 x 8] 
Groups: id [4] 

P1 F1 P2 F2 id pass_rate pass_rate1 pass_rate2 
(int) (int) (int) (int) (int)  (dbl)  (dbl)  (dbl) 
1  2  0  0  0  1 100.00000 100.00000  NaN 
2  0  2  3  2  2 42.85714 0.00000 60.00000 
3 10  0  2  0  3 100.00000 100.00000 100.00000 
4  8  4  2  1  4 66.66667 66.66667 66.66667 

私はそれは満足のいく答え理由ではないことを知っていますplyrはでなければなりません。dplyrの後に読み込まれますが、それが必要な人を助けるかもしれませんgroup_by(id)。またはplyr::mutate()を使用します。次にplyrの後にdplyrをロードできます。

> Pass %>% 
+  group_by(id) %>% 
+  plyr::mutate(pass_rate = (P1 + P2)/(P1 + P2 + F1 + F2) * 100, 
+   pass_rate1 = P1/(P1 + F1) * 100, 
+   pass_rate2 = P2/(P2 + F2) * 100) 
Source: local data frame [4 x 8] 
Groups: id [4] 

P1 F1 P2 F2 id pass_rate pass_rate1 pass_rate2 
(int) (int) (int) (int) (int)  (dbl)  (dbl)  (dbl) 
1  2  0  0  0  1 100.00000 100.00000  NaN 
2  0  2  3  2  2 42.85714 0.00000 60.00000 
3 10  0  2  0  3 100.00000 100.00000 100.00000 
4  8  4  2  1  4 66.66667 66.66667 66.66667 
+0

私は決して考えなかったことがあります。魅力的な副作用。 – Benjamin

+0

これは 'group_by'が' plyr'を読み込んだ後で動作しないことが主な原因だと思います。 – jeremycg

関連する問題