2012-01-17 23 views
13

¿Cómo se puede implementar el operador de tubería directa F # en R? El operador permite encadenar fácilmente una secuencia de cálculos. Por ejemplo, cuando se tiene una entrada data y desea llamar funciones foo y bar en secuencia, se puede escribir:cómo implementar el operador de tubería directa F # en R?

data |> foo |> bar 

En lugar de escribir bar(foo(data)). Los beneficios son que evita algunos paréntesis y los cálculos se escriben en el mismo orden en el que se ejecutan (de izquierda a derecha). En F #, el operador se define como sigue:

let (|>) a f = f a 

Al parecer% ...% se puede utilizar para los operadores binarios, pero ¿cómo funcionaría esto?

+6

Ayudaría mucho si nos dijera un poco más claramente lo que se suponía que debía hacer este operador, así que no teníamos que buscar la información por nosotros mismos. Tal vez su pregunta lo dice, pero es demasiado telegráfico para mí. –

Respuesta

17

no sé qué tan bien podría contener hasta cualquier uso real, pero esto parece (?) para hacer lo que quiera, al menos para funciones de argumento único ...

> "%>%" <- function(x,f) do.call(f,list(x)) 
> pi %>% sin 
[1] 1.224606e-16 
> pi %>% sin %>% cos 
[1] 1 
> cos(sin(pi)) 
[1] 1 
+0

PS 'do.call' puede ser redundante - el cuerpo de la función podría ser simplemente' f ​​(x) ', aunque si quisiera permitir múltiples argumentos à la' list (1,5)%>% [atrás -quote] x [back-quote] 'necesitaría' do.call' ... –

5

El problema es que estás hablando de paradigmas completamente diferentes de funciones de llamada, por lo que no está muy claro lo que quieres. R sólo se utiliza lo que en Fa # sería argumentos de tupla (nombrados en R), así que una forma de pensar que es trivialmente

fp = function(x, f) f(x) 

que se realice la llamada así por ejemplo

> fp(4, print) 
[1] 4 

Esto es equivalente , pero no va a funcionar en caso de no tupple como 4 |> f x y porque no hay tal cosa en R. se podría tratar de emular el comportamiento funcional F #, pero sería incómodo:

fp = function(x, f, ...) function(...) f(x, ...) 

que la voluntad siempre sea funcional y por lo tanto el encadenamiento funcionará así por ejemplo

> tri = function(x, y, z) paste(x,y,z) 
> fp("foo", fp("mar", tri))("bar") 
[1] "mar foo bar" 

pero dado que R no convierte las llamadas incompletas en funciones que no es realmente útil. En cambio, R tiene llamadas mucho más flexibles basadas en el concepto de tupla. Tenga en cuenta que R utiliza una mezcla de paradigma funcional e imperativo, no es puramente funcional para que no se realice valor del argumento coincidente etc.

Editar: ya ha cambiado la pregunta que usted está interesado en la sintaxis y sólo un caso especial, basta con sustituir fp anterior con la notación infija:

`%>%` = function(x, f) f(x) 
> 1:10 %>% range %>% mean 
[1] 5.5 

(Usando el operador de Ben;))

7

Editar: paquete ahora en CRAN. Ejemplo incluido.

El paquete magrittr está hecho para esto.

install.packages("magrittr") 

Ejemplo:

iris %>% 
    subset(Sepal.Length > 5) %>% 
    aggregate(. ~ Species, ., mean) 

También, ver la viñeta: http://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html Tiene un buen número de características útiles si te gusta la tubería # F, y quién no ?!

+0

¿Podría mostrar un ejemplo de uso? – krlmlr

Cuestiones relacionadas