我正在尝试将R中的@
操作符转换为S3系统的通用函数。
基于编写R扩展中的章节:添加新的泛型我试着实现@
的泛型如下:
`@` <- function(object, name) UseMethod("@")
`@.default` <- function(object, name) base::`@`(object, name)
然而,这似乎不起作用,因为它破坏了S4方法的@
。我使用Matrix
包作为S4示例的示例:
Matrix::Matrix(1:4, nrow=2, ncol=2)@Dim
@.default
(Matrix::Matrix(1:4,nrow = 2,ncol = 2),Dim)中的错误:类“dgeMatrix”的此对象没有名称为“name”的插槽
如何实现泛型@
,以便在S4类的情况下正确调度?
编辑
也对为什么这可能不是一个好主意的意见感兴趣?
2条答案
按热度按时间yzckvree1#
R的文档对于
@
是否已经是泛型有点混乱:@
的帮助页面说它是,但它没有列在internalGenerics
页面上。@
操作符有特定的行为,也可能是一个泛型。从@
的帮助页面:“检查对象是否是S4对象(参见isS 4),尝试在任何其他对象上使用@是错误的。”这似乎排除了为S3类编写方法的可能性,尽管文档不清楚这种检查是发生在方法分派之前(如果有的话)还是之后(如果您为某些S3类提供了特定的方法,则可以跳过它)。你可以通过完全重新定义
@
来实现你想要的东西,沿着评论中的建议:但有两个理由不这样做:
1)一旦有人加载了你的包,它就会取代普通的
@
函数,所以如果人们用其他S4对象调用它,他们得到的是你的版本,而不是R的基础版本。2)这个版本比内部版本的效率要低得多,因为(1)你只是强迫你的用户使用它(除非他们使用麻烦的结构
base::"@"(e1,e2)
)。效率可能对你的用例无关紧要,但它可能对你的用户使用S4的其他代码很重要。实际上,一个合理的折衷方案可能是定义自己的二元运算符
%@%
,并使用默认方法调用@
。这在实践中称为:
nqwrtyyt2#
在R 4.3.0及更新版本中,
@
运算符将在内部是S3泛型的,如最新的NEWS中所述:@
运算符现在是一个S3泛型。基于Tomasz Kalinowski在PR#18482中的贡献。如果你不想等待4月21日发布的R 4.3.0,你可以在R-devel上进行测试: