Подтвердить что ты не робот

Возможна ли ассоциативность справа налево в R?

Я новичок в R, и я только что обнаружил, что страдаю от Bracket Phobia (см. комментарий в ссылке). Мне нравится способ обозначения magrittr %>%, потому что он избегает вложенных скобок в некоторых ситуациях и делает код более читаемым. Я пришел из Mathematica, где есть очень похожая натурная нотация //, которая делает то, что делает %>%. Вот некоторые сравнения R и Mathematica:

#R Notation    
c(1.5,-2.3,3.4) %>% round %>% abs %>% sum  

#Mathematica Notation
{1.5,-2.3,3.4}//Round//Abs//Total

Пока все хорошо, но, мой вопрос:

Есть ли способ подражать Mathematica @notation, с ассоциативностью справа налево в R?

Вот как это работает в Mathematica, чтобы решить тот же код выше:

[email protected]@[email protected]{1.5,-2.3,3.4}

В Mathematica он также может быть записан как:

Total[Abs[Round[{1.5,-2.3,3.4}]]]

как и в R, это будет:

sum(abs(round(c(1.5,-2.3,3.4))))

Но было бы намного чище (и прохладно) иметь в R что-то вроде этого:

[email protected]@[email protected](1.5,-2.3,3.4)

PS: Я знаю, что @ используется в классах S4, и это не очень хорошая идея. Это просто иллюстративное сравнение.

4b9b3361

Ответ 1

Для этой цели был разработан и создан пакет backpipe. Он обеспечивает оператора обратной связи (справа налево) для magrittr, pipeR и вообще для любого оператора прямой трубы. backpipe можно найти на github и CRAN.

library(magrittr)  # or library(pipeR)
library(backpipe)

x <- c(1.5,-2.3,3.4)
sum %<% abs %<% round %<% x

all.equal(                             # TRUE
      x %>% round %>% abs %>% sum,
      sum %<% abs %<% round %<% x
)

backpipe также не ограничена дополнительными параметрами, как в случае с решением @BenBolker. Это, например, работает с backpipe:

mean(na.rm=TRUE) %<% c(1:3,NA)  

См. также обсуждение проблемы magrittr github, которая обсуждает это.

Ответ 2

Я вообще не тестировал/не думал об этом, но определение состава функции с помощью оператора (как показано ниже), похоже, работает в нескольких тестовых случаях:

library(magrittr)

## operator defined as  "left-pointing arrow" at the 
##    suggestion of @ClausWilke:
"%<%" <- function(x,y) { if (is(y,"function")) 
          function(z) x(y(z)) 
      else x(y) }

x <- c(1.5,-2.3,3.4)
all.equal(x %>% round %>% abs %>% sum,
          sum %<% abs %<% round %<% x)

x <- rnorm(1000)
all.equal(x %>% round %>% abs %>% sum,
          sum %<% abs %<% round %<% x)

Синтаксис не так хорош, как возможность использовать один символ (например, @) для оператора композиции, но даже если вы можете найти неиспользуемый (все очевидные [[email protected]#$%^&*~|] приняты и маскирование их было бы ужасной идеей) существует ограничение парсера: пользовательские двоичные операторы в R должны иметь вид %?%.

Ответ 3

Как насчет использования compose из пакета hadley purrr?

compose(sum,abs,round,c)(1.5,-2.3,3.4)