Как реализовать оператор прямой трубы F # в R? - программирование
Подтвердить что ты не робот

Как реализовать оператор прямой трубы F # в R?

Как вы можете реализовать оператор прямой трубы F # в R? Оператор позволяет легко наследовать последовательность вычислений. Например, когда у вас есть вход data и вы хотите последовательно вызывать функции foo и bar, вы можете написать:

data |> foo |> bar

Вместо записи bar(foo(data)). Преимущества заключаются в том, что вы избегаете некоторых круглых скобок, и вычисления записываются в том же порядке, в котором они выполняются (слева направо). В F # оператор определяется следующим образом:

let (|>) a f = f a

Похоже, что%...% может использоваться для двоичных операторов, но как это работает?

4b9b3361

Ответ 1

Я не знаю, насколько это хорошо подходит для любого реального использования, но это кажется (?), чтобы делать то, что вы хотите, по крайней мере для функций с одним аргументом...

> "%>%" <- 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

Изменить: пакет теперь на CRAN. Пример включен.

Для этого создан пакет magrittr.

install.packages("magrittr")

Пример:

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

Также см. виньетку: http://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html У вас есть много полезных функций, если вам нравится трубка F #, а кто нет?!

Ответ 3

Проблема заключается в том, что вы говорите о совершенно разных парадигмах функций вызова, поэтому не совсем понятно, что вы хотите. R использует только то, что в F # было бы кортевым аргументом (названным в R), поэтому один из способов думать о нем тривиально

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

который будет выполнять вызов, например,

> fp(4, print)
[1] 4

Это эквивалентно, но не будет работать в случае, отличном от 4 |> f x y, потому что в R не существует такой вещи. Вы могли бы попытаться подражать функциональному поведению F #, но было бы неудобно:

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

Это будет всегда функционировать, и поэтому цепочка будет работать так, например,

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

но поскольку R не конвертирует неполные вызовы в функции, это не очень полезно. Вместо этого R имеет гораздо более гибкий вызов, основанный на концепции кортежа. Обратите внимание, что R использует смесь функциональной и императивной парадигмы, она не является чисто функциональной, поэтому не выполняет сопоставление значений аргументов и т.д.

Изменить:, так как вы изменили вопрос в том, что вас интересует синтаксис и только особый случай, просто замените fp выше на нотацию infix:

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

(с использованием оператора Бена;))