2016-05-22 19 views
0

Ich habe einen Datenrahmen insgesamt Studenten (Stu) und die Anzahl der Teilnehmer pro Gruppe (ID) die Auflistung, die an einer Tätigkeit (Sub) einnehmen:COUNTIF äquivalent in dplyr zusammenfassen

 ID Stu Sub 
    (int) (int) (int) 
1 101 80 NA 
2 102 130 NA 
3 103 10 NA 
4 104 210 20 
5 105 180 NA 
6 106 150 NA 

Ich mag würde zu weiß die Anzahl der Gruppen in Größenklassen (> 400> 200> 100> 0), die entweder an einer Aktivität beteiligt sind (Sub> 0) oder nicht (Sub is.na)

output <- structure(list(ID = c(101L, 102L, 103L, 104L, 105L, 106L), 
         Stu = c(80L, 130L, 10L, 210L, 180L, 150L), 
         Sub = c(NA,NA, NA, 20L, NA, NA)), 
        .Names = c("ID", "Stu", "Sub"), 
        class = c("tbl_df", "data.frame"), 
        row.names = c(NA, -6L)) 

temp <- output %>% 
mutate(Stu = ifelse(Stu >= 400, 400, 
     ifelse(Stu >= 200, 200, 
      ifelse(Stu >= 100, 100, 0 
       )))) %>% 
group_by(Stu) %>% 
summarise(entries = length(!is.na(Sub)), 
      noentries = length(is.na(Sub))) 

die Ergebnisse sollten sein:

Stu entries noentries 
    (dbl) (int)  (int) 
1  0  0   2 
2 100  0   3 
3 200  1   0 

Aber ich bekomme:

Stu entries noentries 
    (dbl) (int)  (int) 
1  0  2   2 
2 100  3   3 
3 200  1   1 

Wie kann ich die Länge Funktion im summarise wirken wie ein countIf machen?

+0

etw in Ihrem letzten IFEL falsch ist se –

+0

sorry, verpasste eine 0, sollte es jetzt funktionieren – pluke

+0

'sum' ist die richtige Lösung wie unten erwähnt. Aus Gründen der Klarheit gibt die Länge die Länge des bereitgestellten Vektors zurück. In diesem Fall gibt die Längenfunktion unabhängig von den Wahr/Falsch-Werten die Anzahl der Elemente in jeder Gruppe zurück. – Gopala

Antwort

1

summarise erwartet einen einzigen Wert, so sum statt length macht den Job:

output %>% 
    mutate(Stu = ifelse(Stu >= 400, 400, 
         ifelse(Stu >= 200, 200, 
          ifelse(Stu >= 100, 100, 0 
          )))) %>% 
    group_by(Stu) %>% 
    summarise(entries = sum(!is.na(Sub)), 
      noentries = sum(is.na(Sub))) 

Source: local data frame [3 x 3] 

Stu entries noentries 
(dbl) (int)  (int) 
1  0  0   2 
2 100  0   3 
3 200  1   0 
+0

ah ja, ich habe vergessen, dass is.na gibt einen Vektor von Boolean, der summiert werden kann – pluke

1

Eine weitere Option Gruppe ist sowohl durch Stu und Sub, sondern das zu tun, müssen wir zunächst die Werte von Sub recode und Stu, um die gewünschten Ausgabegruppen zu finden. Wir verwenden auch cut, anstelle von verschachtelten ifelse, den Wert bricht in Stu einzustellen:

library(reshape2) 

output %>% 
    group_by(Sub=ifelse(is.na(Sub), "No Entries", "Entries"), 
      Stu=cut(Stu, c(0,100,200,400,Inf), labels=c(0,100,200,400))) %>% 
    tally %>% 
    dcast(Stu ~ Sub, fill=0) 
 Stu Entries No Entries 
1  0  0   2 
2 100  0   3 
3 200  1   0 
3

Nach der gleichen Idee, die von @ eipi10, aber mit count() statt auf die Jagd schneiden group_by() %>% tally() und dass tidyr::spread zeigt nachahmen kann reshape2::dcast:

output %>% 
    count(Sub = ifelse(is.na(Sub), 'No Entries', 'Entires'), 
     Stu = cut(Stu, c(0, 100, 200, 400, +Inf), labels = c(0, 100, 200, 400))) %>% 
    tidyr::spread(Sub, n, fill = 0)