Как определить оператор%>%? - PullRequest
1 голос
/ 20 сентября 2019

Мне нужен другой оператор с теми же функциями, что и у магритта%>%.

Я пытался

"%myop%" <- function(x,f) do.call(f, list(x))

, но это не работает.

Я ожидаю, что моя функция с правой стороны будет решена с аргументом с левой стороны, например:

> p<-10
> p %>% log()
[1] 2.302585

, который равен x%>% f и может быть переписан как f (x)

x%>% f (a, b), который может быть переписан как f (x,а, б) - и это не работает

Как я могу это определить?

1 Ответ

1 голос
/ 20 сентября 2019

Вы можете проверить реализацию magrittr , но, если честно, код довольно сложный, поскольку он делает намного больше.

Проще говоря, для поддержки семантики, которую вы хотите, чтобы вынеобходимо извлечь неоцененную RHS выражения и вставить в нее неоцененную LHS перед его оценкой.

Выражение вызова функции - это список, в котором имя функции является ее первым элементом, а остальные аргументы -последующие элементы.Поэтому вам нужно вставить значение LHS в этот список на второй позиции.

Затем вам нужно превратить полученный список обратно в вызов - as.call делает это:

`%>%` = function (lhs, rhs) {
    lhs = substitute(lhs)
    rhs = substitute(rhs)

    if (is.name(rhs)) {
        do.call(as.character(rhs), list(lhs))
    } else if (is.call(rhs)) {
        rhs = as.list(rhs)
        call = as.call(c(rhs[[1L]], list(lhs), rhs[-1L]))
        eval.parent(call)
    } else {
        stop('Unsupported RHS')
    }
}

Помните, что, поскольку эта реализация вставляет неоцененный LHS в вызов RHS, цепной конвейер будет оцениваться справа налево.То есть этот

(1 : 5) %>% sapply(`*`, 2) %>% sum()

будет преобразован в следующее:

sum(sapply((1: 5), `*`, 2))

до оценки любого компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...