В R, как я могу определить приоритет оператора для определенных пользователем инфиксных операторов?

Предположим, у меня есть два пользовательских инфиксных оператора в R: %foo% и %bar%.

У меня есть выражения, в которых используются оба оператора, например:

x %foo% y %bar% z

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

Как изменить приоритет, чтобы, например, %bar% всегда выполнялось перед %foo%? В приведенном выше примере это будет так же, как:

x %foo% (y %bar% z)

person sdgfsdh    schedule 25.06.2015    source источник


Ответы (2)


Я не думаю, что это явно задокументировано, но подразумевается в документация по языку R заключается в том, что все инфиксные операторы имеют одинаковый приоритет и поэтому выполняются слева направо. Это можно продемонстрировать следующим образом:

`%foo%` <- `+`
`%bar%` <- `*`
1 %bar% 2 %foo% 3
#5
1 %foo% 2 %bar% 3
#9

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

Также стоит отметить, что использование substitute не меняет приоритет оператора, уже установленный при первой записи выражения:

eval(substitute(2 + 2 * 3, list(`+` = `*`, `*` = `+`)))
#10
2 * 2 + 3
#7
person Nick Kennedy    schedule 25.06.2015

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

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

Одна из причин этого ограничения заключается в том, что было бы чрезвычайно сложно реализовать и поддерживать набор правил старшинства для инфиксных операторов. Представьте, что вы загрузили пакет R, который поставляется с некоторыми пользовательскими инфиксными операторами. Затем необходимо определить отношение инфиксных операторов из пакета к созданным вами %foo% и %bar%. Это быстро станет серьезным бременем.

В качестве примера представьте, что первый пакет содержит инфиксный оператор %P1IF%, а второй пакет содержит инфиксный оператор %P2IF%. Каждый пакет определил, что его инфиксный оператор должен иметь наивысший приоритет. Если бы вы загружали и первый, и второй пакет, то следующее выражение было бы неопределенным:

v1 %P1IF% v2 %P2IF% v3
(v1 %P1IF% v2) %P2IF% v3     # package 2 doesn't expect this
v1 %P1IF% (v2 %P2IF% v3)     # package 1 doesn't expect this

Независимо от того, каким может быть приоритет, результат для одного из двух пакетов может быть неправильным.

person Tim Biegeleisen    schedule 25.06.2015