2015-06-25 22 views
5

Supponiamo di avere due operatori di infisso personalizzati in R: %foo% e %bar%.In R, come è possibile determinare la precedenza degli operatori di infisso definiti dall'utente?

ho espressioni che utilizzano entrambi gli operatori, come ad esempio:

x %foo% y %bar% z 

Come posso determinare la precedenza degli operatori di %foo% e %bar%?

Come modificare la precedenza in modo che, ad esempio, %bar% venga eseguito sempre prima del %foo%? Nell'esempio di cui sopra questo sarebbe lo stesso:

x %foo% (y %bar% z) 

risposta

5

Io non credo che questo è esplicitamente documentata, ma implicito nel R language documentation è che operatori infissi sono tutti uguali precedenza e quindi vengono eseguiti da sinistra verso destra . Questo può essere dimostrato come segue:

`%foo%` <- `+` 
`%bar%` <- `*` 
1 %bar% 2 %foo% 3 
#5 
1 %foo% 2 %bar% 3 
#9 

L'unica opzione che viene in mente è quello di ridefinire uno degli operatori esistenti per fare quello che si voleva. Tuttavia, quello stesso avrebbe ripercussioni quindi potresti volerlo limitare a una funzione.

E 'anche interessante notare che utilizzando substitute non cambia la precedenza degli operatori già impostato quando l'espressione viene prima scritto:

eval(substitute(2 + 2 * 3, list(`+` = `*`, `*` = `+`))) 
#10 
2 * 2 + 3 
#7 
2

Come posso determinare la precedenza degli operatori del% pippo% e% bar% ?

Non è possibile. R non ti consente di impostare la precedenza degli operatori di infissi personalizzati. Gli operatori di infissi definiti dall'utente hanno le regole di precedenza predefinite, il che significa che verranno valutate da sinistra a destra.

Una ragione di questa limitazione è che sarebbe estremamente difficile e limitante implementare e mantenere un insieme di regole di precendenza per gli operatori infissi. Immagina di aver caricato un pacchetto R che viene fornito con alcuni operatori di infissi personalizzati. Quindi è necessario definire la relazione degli operatori infissi dal pacchetto allo %foo% e %bar% che è stato creato. Questo diventerà presto un onere serio.

Ad esempio, immaginare che il pacchetto 1 contenga l'operatore infisso %P1IF% e il pacchetto due contenga l'operatore infisso %P2IF%. Ogni pacchetto ha definito che il proprio operatore infisso dovrebbe avere la precedenza più alta. Se si dovesse caricare sia il pacchetto uno e due, quindi la seguente espressione sarebbe undefined:

v1 %P1IF% v2 %P2IF% v3 
(v1 %P1IF% v2) %P2IF% v3  # package 2 doesn't expect this 
v1 %P1IF% (v2 %P2IF% v3)  # package 1 doesn't expect this 

Indipendentemente da ciò che la precedenza potrebbe essere il risultato di uno dei due pacchetti potrebbero non essere corrette.