2016-06-23 24 views
2

Diese Frage ist angemessen, um die richtige Funktionalität der Funktion group_by zu verstehen.In R, wie funktioniert group_by in dplyr?

Angenommen, ich habe einen Datenrahmen mit 5 binären Variablen (die Bedeutung dieser Variablen ist nicht wichtig) und eine variable ID, die einige Benutzer darstellt. Zum Beispiel:

id<- c("A","A" , "B" , "B") 
d<- as.data.frame(id) 
d$d1<- c(1,0,1,0) 
d$d2<- c(1,0,1,0) 
d$d3<- c(0,1,1,0) 
d$d4<- c(0,1,0,1) 
d$d5<- c(0,1,0,0) 
> d 
    id d1 d2 d3 d4 d5 
1 A 1 1 0 0 0 
2 A 0 0 1 1 1 
3 B 1 1 1 0 0 
4 B 0 0 0 1 0 

I eine Funktion der Lage, zu überprüfen, dass für jeden Benutzer, A und B, die Variablen d1 bis d5 enthält 1 in alle von ihnen konstruieren. B. für den Benutzer A, für jeden d1 bis d5 gibt es die Nummer eins in allen von ihnen.

verificator(d[1:2,]) 
[1] TRUE 

Aber für den B-Benutzer haben wir

verificator(d[3:4,]) 
[1] FALSE 

Wenn ich die dplyr Funktion verwenden, um die d-Matrix zu bewerten, ist etwas nicht in Ordnung:

d2<- d %>% group_by(id) %>% summarise(one = verificator(.)) 
d2 
Source: local data frame [2 x 2] 

    id one 
1 A TRUE 
2 B TRUE 

Warum tut dies für den B-Benutzer TRUE zurückgeben?

+1

ich bin mir nicht sicher, ob es die anmutigsten, aber ich würde wahrscheinlich tun 'd%>% group_by (id)%>% summarise_each (Spaße (sum))%>% group_by (id) %>% summieren (eins = als .logisch (prod (d1: d5))) ' – alistaire

Antwort

3

Wenn wir die erwartete Ausgabe, eine Option ist

d %>% 
    group_by(id) %>% 
    summarise_each(funs(sum)) %>% rowwise() %>% 
    do(data.frame(id = .[1L], one = as.logical(prod(unlist(.[-1]))))) 
#  id one 
# <fctr> <lgl> 
#1  A TRUE 
#2  B FALSE 

Wir können dies auch mit by bekommen müssen aus base R

verificator <- function(x){ 
    as.logical(prod(colSums(x))) 
    } 
c(by(d[-1], d$id, FUN = verificator)) 
# A  B 
#TRUE FALSE 
2

Der Grund, dass Sie ein falsches Ergebnis erhalten, ist, dass bei Verwendung von %>% der Punkt (.) für das konkurrierende Ergebnis des Ausdrucks links von %>% steht. Daher werten Sie einfach Ihre verificator() zweimal auf dem vollständigen Datenrahmen d aus.

Sie können dies wie folgt sehen. Erstens, ich überprüfen, ob verificator() auf den kompletten Datenrahmen angewandt in der Tat gibt TRUE:

verificator(d) 
## [1] TRUE 

Dann definiere ich eine andere Variante verificator(), die ihr Argument druckt:

verificator_p <- function(d) { 
    print(d) 
    return(verificator(d)) 
} 

den Code verwenden, die Sie vorgeschlagen, zeigt, dass es immer der volle Datenrahmen ist, der an die Funktion übergeben wird:

d %>% group_by(id) %>% summarise(one = verificator_p(.)) 
## Source: local data frame [4 x 6] 
## Groups: id [2] 
## 
##  id d1 d2 d3 d4 d5 
## (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) 
## 1  A  1  1  0  0  0 
## 2  A  0  0  1  1  1 
## 3  B  1  1  1  0  0 
## 4  B  0  0  0  1  0 
## Source: local data frame [4 x 6] 
## Groups: id [2] 
## 
##  id d1 d2 d3 d4 d5 
## (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) 
## 1  A  1  1  0  0  0 
## 2  A  0  0  1  1  1 
## 3  B  1  1  1  0  0 
## 4  B  0  0  0  1  0 
## Source: local data frame [4 x 6] 
## Groups: id [2] 
## 
##  id d1 d2 d3 d4 d5 
## (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) 
## 1  A  1  1  0  0  0 
## 2  A  0  0  1  1  1 
## 3  B  1  1  1  0  0 
## 4  B  0  0  0  1  0 
## Source: local data frame [2 x 2] 
## 
##  id one 
## (fctr) (lgl) 
## 1  A TRUE 
## 2  B TRUE 

Was ich zugegebenermaßen nicht k jetzt, warum d dreimal gedruckt und nicht nur zweimal ...

+0

> d2 <- d %>% group_by (id)%>% zusammenfassen (one = verificator()) Fehler: Argument" d "fehlt, ohne Standard – Vasco

+0

Aufruf' Verifikator () 'ohne ein Argument funktioniert definitiv nicht ... Andere waren schneller, um eine funktionierende Lösung zu bieten.Aber ich habe weitere Erklärungen hinzugefügt, die Ihnen hoffentlich helfen werden zu verstehen, warum Ihr erster Ansatz nicht wie erwartet funktioniert hat. – Stibu

Verwandte Themen