Нет блестящего решения для этого, которое полностью находится под вашим контролем.
Пакет tidyverse
может вызывать class<-
для любого данного объекта, подобного фрейму данных, и, как вы видели, это разрушит природу S4 любого объекта. Это нельзя обойти, например, путем определения метода для coerce
или вызова setAs
, так как class<-
не использует этот механизм. (class<-
также не является универсальным c, вы не можете установить для него метод.) Единственный способ заставить tidyverse
поддерживать S4 - это для автора tidyverse
изменить код для использования as
или похожий, и это не похоже на то, что это верхняя часть их списка дел.
Вы правы, что беспокоитесь о том, чтобы резко изменить работу вашего класса, когда вы выпустили версию своего пакет уже с классом S4.
Если:
- ваш пакет довольно новый и еще не имеет большого количества пользователей;
- вы можете делать все, что вам нужно делать с S3; и
- вы не знаете другого пакета, который построил новые классы поверх вашего
, тогда может быть лучше переопределить его как S3 и добавить сообщение, когда ваш пакет установлен или загружен, чтобы сказать
спасибо за установку myPackage v2. Код может быть несовместим с v1.2 или более ранней версией; подробности см. в справке (бла)
в противном случае придерживайтесь S4.
Вы не можете точно смешать S3 и S4 для определений классов (вы можете для определений методов). Самое близкое, что вы можете получить, это setOldClass
, который регистрирует класс S3 как класс S4 (тогда как вы хотели наоборот). Тем не менее, это может помочь вам достичь «вы можете делать все, что вам нужно делать с S3» выше.
Еще одна возможность - определить собственную версию class<-
, которая проверяет, является ли объект класса S4 foobar
пытается привести к S3
и вызывает обычный class<-
, если нет. Лечение, вероятно, хуже, чем болезнь в этом случае; это замедлит все будущие преобразования класса S3 (поскольку class<-
теперь является обычным вызовом функции, а не примитивом), но это должно работать в принципе. Другая причина, по которой это не рекомендуется, заключается в том, что вы не полагаетесь на то, что другой пакет выше в пути поиска делает что-то похожее (что, если другой автор пакета столкнулся с той же проблемой и захотел сделать тот же трюк? Тогда результаты будут зависеть от того, какой пакет был выше по пути search
)