2016-06-09 18 views
6

Ho attraversato una situazione in cui %>% produce un output molto sorprendente se combinato con !. Considera il seguente codice:Uso di! (o qualsiasi operatore logico) con%>% (magrittr) produce output imprevisto

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, niente di sorprendente lì. Ma se provo per accorciarlo utilizzando %>% roba strana che accade:

!is.na(x) %>% sum 

[1] TRUE 

TRUE ?? Non è quello che mi aspettavo, dovrebbe essere 20.

Se rimuovo il ! mi dà 0 come previsto:

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

e se aggiungo tra parentesi funziona:

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

e trattare ! in funzione funziona:

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

Cosa fa !is.na(x) %>% sum e perché restituisce TRUE anziché 20?

EDIT: Gli altri operatori logici producono comportamento simile:

> 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' o 'Negate (is.na) (x)%>% sum' – rawr

+0

O in magrittr speak' is.na (x)%>% not%>% sum' –

+2

@RichardScriven il mio preferito magrittr speak è 'is_weakly_greater_than' per '> =' – rawr

risposta

6

sospetto che è un ordine di rilascio operazioni:

!is.na(x) %>% sum 

sta valutando di

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

Che è equivalente a TRUE

4

Anche se ho accettato la risposta di @ C-Z_, voglio aggiungerne un'altra per fornire un contesto su questo. Grazie a @rawr per avermi indirizzato a ?Syntax.

Fondamentalmente %>% è considerato un operatore, come %in% e come tale deve rispettare l'ordine delle operazioni. Nella pagina di guida Syntax corrisponde all'operatore %any% (ad esempio qualsiasi operatore infisso), poiché gli utenti possono definirli a piacere. In questo caso, ciò significa che %>% si attiva prima di qualsiasi operatore logico e anche prima di operatori aritmetici (ad esempio * e \). Di conseguenza, se sei ingenuo, come lo ero io, pensando che il lato sinistro di %>% verrà completato prima del prossimo passaggio della catena, puoi ottenere delle sorprese. Per esempio:

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

non fa 3+2=5, 5*4= 20, 20/2=10

invece lo fa 2*4/2=4, 4+3=7, perché il %>% ha la precedenza su +.

Se si utilizzano le funzioni nel pacchetto magrittr come ad esempio:

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

Si ottiene 10 come previsto. Posizionando le parentesi attorno allo 3+2 otterrai anche 10.

Nei miei esempi originali, gli operatori logici, ad esempio !, hanno una precedenza inferiore a %>%, quindi agiscono per ultimi, dopo che la somma ha partecipato.

Morale della trama: fare attenzione a mescolare %>% con altri operatori.

1

È anche possibile utilizzare il "non" alias dal pacchetto magrittr:

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

[1] 20