2015-10-13 9 views
5

Ich arbeite an der Validierung einer Funktion, um die Erfolgsquoten für ein bestimmtes Kriterium in meinem Labor zu berechnen. Die Mathematik dahinter ist sehr einfach: Bei einer Anzahl von bestandenen oder fehlgeschlagenen Tests, welcher Prozentsatz wurde überschritten.dplyr :: muate gibt x/y = NA, fasse zusammen x/y = reelle Zahl

Die Daten werden als eine Spalte von Werten bereitgestellt werden, die entweder P1 (weitergegeben ersten Test) sind, F1 (auf dem ersten Test nicht bestanden), P2 oder F2 (bestanden oder zweiten Test nicht bestanden, jeweils). Ich habe die Funktion passRate unten geschrieben, um bei der Berechnung der Erfolgsquoten insgesamt (erster und zweiter Versuch) und beim ersten Test und zweiten Test isoliert zu helfen.

Der Qualitätsspezialist, der die Parameter für die Validierung eingerichtet hat, hat mir eine Liste der Bestanden- und Fehlgeschlagen-Zählungen gegeben, die ich unter Verwendung der test_vector-Funktion unten in einen Vektor umwandle.

Alles sah gut aus, bis ich in die dritte Zeile des Pass Datenrahmens kam, der die Pass/Fail-Zählungen meines Qualitätsspezialisten enthält. Statt eines zweiten Testdurchlauf von 100% der Rückkehr gibt es NA ... aber nur, wenn ich 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)) 

hier ist so etwas wie das, was ich mit mutate tat.

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 

vergleichen, wenn ich 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 

verwende ich erwartet hätte diese die gleichen Ergebnisse zurückzukehren. Meine Vermutung ist, dass mutate irgendwo Probleme hat, weil es n Zeilen pro Gruppe an n Zeilen im Ergebnis (wird es bei der Berechnung n hier verwirrt?) Wird, während summarise weiß, dass egal, wie viele Zeilen es beginnt, es ist gehe zum Ende mit nur 1.

Hat jemand irgendwelche Gedanken darüber, was die Mechanik hinter diesem Verhalten sind?

+3

Das ist ein wirklich verwickeltes Beispiel. Hast du einen einfacheren, der zeigt, was wie ein Fehler klingt (in deinem Titel)? Hier ist die typische Referenz: [mcve] – Frank

+0

Sie haben recht, ich hatte nicht viel Zeit damit verbracht, es zu entkonvoltieren. Ich habe Code eingegeben, um die Ergebnisse ohne die zusätzlichen Funktionen zu berechnen. – Benjamin

+4

Scheint wie ein Fehler: 'Pass <- data.frame (P2 = c (0,3,2), F2 = c (0,2,0), id = 1: 3); Übergeben Sie%>% group_by (id)%>% mutieren (pass2 = P2/(P2 + F2)) '. Es sollte keine NA in Zeile 3 geben – jeremycg

Antwort

3

Es scheint mir etwas Interferenz zwischen dplyr und plyr. Ich hatte das gleiche Problem mit einem anderen unsymmetrischen Datensatz (also Gruppierung war notwendig), wo genau in der dritten Gruppe die mutierte Variable fälschlicherweise NA war! Dann habe ich dein Beispiel zu Hause reproduziert. Zuerst, nach

Ich habe genau Ihre Ergebnisse. Dann habe ich mein eigenes Skript ausgeführt, wo das Paket plyr geladen wurde. Nach der Warnung, plyr nach dplyr nicht zu laden, war die NA in meiner dritten Gruppe weg und auch Ihr Beispiel wurde korrekt berechnet! Hier ist, was ich getan habe (ich eine weitere Zeile hinzugefügt, um zu sehen, ob NA in der dritten Gruppe bleibt):

> 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 

Dann habe ich:

> 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 

Ich weiß, dass es nicht eine befriedigende Antwort ist, weil plyr sollte NICHT nach dplyr geladen werden, aber vielleicht hilft es denen, die group_by(id) benötigen. Oder verwenden Sie plyr::mutate().Dann können Sie laden dplyr nach plyr:

> 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

Da ist etwas, an das ich nie gedacht hätte. Faszinierender Nebeneffekt. – Benjamin

+0

Ich denke, das liegt hauptsächlich daran, dass 'group_by' nach dem Laden von' plyr' nicht funktioniert. – jeremycg