问题
How can you implement F#'s forward pipe operator in R? The operator makes it possible to easily chain a sequence of calculations. For example, when you have an input data
and want to call functions foo
and bar
in sequence, you can write:
data |> foo |> bar
Instead of writing bar(foo(data))
. The benefits are that you avoid some parentheses and the computations are written in the same order in which they are executed (left-to-right). In F#, the operator is defined as follows:
let (|>) a f = f a
It would appear that %...% can be used for binary operators, but how would this work?
回答1:
I don't know how well it would hold up to any real use, but this seems (?) to do what you want, at least for single-argument functions ...
> "%>%" <- function(x,f) do.call(f,list(x))
> pi %>% sin
[1] 1.224606e-16
> pi %>% sin %>% cos
[1] 1
> cos(sin(pi))
[1] 1
回答2:
Edit: package now on CRAN. Example included.
The magrittr package is made for this.
install.packages("magrittr")
Example:
iris %>%
subset(Sepal.Length > 5) %>%
aggregate(. ~ Species, ., mean)
Also, see the vignette:http://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html It has quite a few useful features if you like the F# pipe, and who doesn't?!
回答3:
The problem is that you are talking about entirely different paradigms of calling functions so it's not really clear what you want. R only uses what in F# would be tuple arguments (named in R), so one way to think of it is trivially
fp = function(x, f) f(x)
which will perform the call so for example
> fp(4, print)
[1] 4
This is equivalent, but won't work in non-tupple case like 4 |> f x y
because there is no such thing in R. You could try to emulate the F# functional behavior, but it would be awkward:
fp = function(x, f, ...) function(...) f(x, ...)
That will be always functional and thus chaining will work so for example
> tri = function(x, y, z) paste(x,y,z)
> fp("foo", fp("mar", tri))("bar")
[1] "mar foo bar"
but since R doesn't convert incomplete calls into functions it's not really useful. Instead, R has much more flexible calling based on the tuple concept. Note that R uses a mixture of functional and imperative paradigm, it is not purely functional so it doesn't perform argument value matching etc.
Edit: since you changed the question in that you are interested in syntax and only a special case, just replace fp
above with the infix notation:
`%>%` = function(x, f) f(x)
> 1:10 %>% range %>% mean
[1] 5.5
(Using Ben's operator ;))
来源:https://stackoverflow.com/questions/8896820/how-to-implement-fs-forward-pipe-operator-in-r