нечисловой аргумент бинарного оператора при определении метода data.frame для `+` и использовании объекта ggplot - PullRequest
2 голосов
/ 06 марта 2019

Я могу определить метод S3 следующим образом:

`+.data.frame` <- function(e1,e2){"hello"}
iris + iris
# [1] "hello"

Но это не сработает, если e2 является gg объектом:

iris + geom_point()

Ошибка в iris + geom_point (): не числовой аргумент для бинарного оператора

Дополнительно: предупреждающее сообщение: несовместимые методы ("+ .data.frame", "+ .gg") для "+"

Я думаю, что это как-то связано с методами S4, но я в замешательстве. Можете ли вы объяснить, что происходит и как с этим разобраться?

желаемый вывод:

iris + geom_point()
# [1] "hello"

1 Ответ

4 голосов
/ 06 марта 2019

Это на самом деле не из-за методов S4, а из-за конфликта методов.Ни geom_point(), ни ваш фрейм данных не являются объектами S4 (isS4 на любом из них возвращает FALSE), поэтому методы S4 не будут задействованы.

Пакет ggplot определяет метод для +для gg -классированных объектов, и вы только что определили метод для data.frame s.Проблема, в отличие от большинства универсальных функций S3, + учитывает класс обоих аргументов при выборе метода.В этом случае он приходит к выводу, что он мог законно выбрать метод gg, а также метод data.table.

На странице справки для «Ops» (членом которой является «+»):

Классы обоих аргументов учитываются при отправке любого члена этой группы.Для каждого аргумента проверяется его вектор классов, чтобы увидеть, существует ли соответствующий специфический (предпочтительный) метод или метод Ops.Если метод найден только для одного аргумента или один и тот же метод найден для обоих, он используется.Если найдены разные методы, появляется предупреждение о «несовместимых методах»: в этом случае или если ни один из аргументов не найден для какого-либо аргумента, используется внутренний метод.

Итак, вы видите в этом случае,он возвращается к стандартному коду +, который не знает, как добавить фреймы данных и gg объекты, и возвращает ошибку, в которой говорится столько же.

Для решения этой проблемы вы можетенаписать метод S4 с подписью (data.frame,gg) (или, возможно, (data.frame,ANY), но будьте осторожны - он будет фактически вызываться только в том случае, если один из аргументов является объектом S4 (который data.frames не является по умолчанию). Возможно, вам придется определитьВаш собственный класс, который содержит data.frame (или, альтернативно, содержит gg) для запуска метода.

...