2016-06-09 22 views
6

Ich habe eine Situation überstanden, in der %>% eine sehr überraschende Ausgabe ergibt, wenn sie mit ! kombiniert wird. Betrachten Sie den folgenden Code:Verwendung von! (oder irgendein logischer Operator) mit%>% (magrrittr) erzeugt eine unerwartete Ausgabe

x <- c(1:20) 
y <- !is.na(x) 

> y 
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 
    TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 

> sum(Y) 
[1] 20 

Ok, nichts überraschend dort. Aber wenn ich versuche, es zu verkürzen %>% seltsame Dinge mit dabei:

!is.na(x) %>% sum 

[1] TRUE 

TRUE ?? Nicht was ich erwartet habe - es sollte 20 sein.

Wenn ich die ! entfernen es gibt mir 0 wie erwartet:

> is.na(x) %>% sum 
[1] 0 

und wenn ich Klammern hinzufügen, funktioniert es:

> {!is.na(x)} %>% sum 
[1] 20 

und ! als Funktion der Behandlung funktioniert:

> is.na(x) %>% `!` %>% sum 
[1] 20 

Was ist !is.na(x) %>% sum tun, und warum tut es gibt TRUE eher als 20 zurück?

EDIT: Die anderen logischen Operatoren erzeugen ein ähnliches Verhalten:

> T&T %>% sum() 
[1] TRUE 
> {T&T} %>% sum() 
[1] 1 

> T|T %>% sum() 
[1] TRUE 
> {T|T} %>% sum() 
[1] 1 
+1

'is.na (x)%>% \' \ '%>% sum' oder 'Negate (is.na) (x)%>% sum' – rawr

+0

Oder in magrittr speak' is.na (x)%>% nicht%>% sum' –

+2

@RichardScriven meine Lieblings-magrittr sprechen 'is_weakly_greater_than' für '> =' – rawr

Antwort

6

Ich vermute, dass es sich um eine Reihenfolge von Operationen Frage ist:

!is.na(x) %>% sum 

wird

Auswertung
!(is.na(x) %>% sum) 

Das entspricht TRUE

4

Obwohl ich die Antwort von @ C-Z_ akzeptiere, möchte ich eine weitere hinzufügen, um einen Kontext dazu bereitzustellen. Danke an @raw, dass er mich zu ?Syntax geleitet hat.

Grundsätzlich %>% gilt als ein Operator, wie %in% und als solche muss es die Reihenfolge der Operationen zu befolgen. Auf der Hilfeseite Syntax entspricht dies dem %any%-Operator (d. H. Jedem Infix-Operator), da Benutzer diese nach Belieben definieren können. Das bedeutet, dass %>% vor jedem logischen Operator und auch vor arithmetischen Operatoren ausgelöst wird (z. B. * und \). Als Ergebnis, wenn Sie naiv sind, wie ich war, denken, dass die linke Seite von %>% vor dem nächsten Schritt in der Kette abgeschlossen ist, können Sie einige Überraschungen bekommen. Zum Beispiel:

3+2 %>% '*'(4) %>% `/`(2) 

Hat nicht 3+2=5, 5*4= 20, 20/2=10

statt es tut 2*4/2=4, 4+3=7, weil die %>% Vorrang vor + hat.

Wenn Sie die Funktionen im magrittr Paket verwenden wie:

add(3,2) %>% multiply_by(4) %>% divide_by(2) 

Sie erhalten 10 wie erwartet. Wenn Sie Klammern um die 3+2 platzieren, erhalten Sie auch 10.

In meinen ursprünglichen Beispielen haben die logischen Operatoren wie ! eine niedrigere Priorität als %>%, also wirken sie zuletzt, nachdem die Summe konkurriert hat.

Moral der Geschichte: Seien Sie vorsichtig Mischen %>% mit anderen Betreibern.

1

Sie können auch die "nicht" alias aus dem magrittr Paket verwenden:

> is.na(1:20) %>% not %>% sum 

[1] 20