gpt4 book ai didi

来自不同包的同名 R S4 类

转载 作者:行者123 更新时间:2023-12-05 06:19:45 33 4
gpt4 key购买 nike

假设有两个包。

Package_A 有这个类:

setClass("Person", 
slots = c(
name = "character",
age = "numeric"
)
)

setGeneric("age", function(x) standardGeneric("age"))
setMethod("age", "Person", function(x) x@age)

Package_B 有一个类似的类:

setClass("Person", 
slots = c(
name = "character",
age = "numeric"
)
)

setGeneric("age", function(x) standardGeneric("age"))
setMethod("age", "Person", function(x) x@age * 10) # notice the difference here

所以用户已经在他们的工作环境中加载了这两个包:

library(Package_A)
library(Package_B)

在这个用户的工作环境中,R 如何解决创建“Person”对象的困惑:

john <- new("Person", name = "John Smith", age = 7)

在这个用户的工作环境中,R 如何解决调用正确的方法:

age(john)

最佳答案

访问特定包中的类

getClass()

new()接受一个 classRepresentation 对象,您可以使用 getClass 检索该对象.例如,new(getClass('className', where='packageName'))。但是,请注意,如果您还没有导入包,并且您已经定义了一个同名的新类,那么这将不会起作用。我在这里演示这个问题:

install.packages('lookupTable')
setClass('lookupTable', slots = c(notworking='numeric'))
new(getClass('lookupTable', where='lookupTable'))
#> An object of class "lookupTable"
#> Slot "notworking":
#> numeric(0)

(它打印了“notworking”槽,这意味着它正在实例化我的自定义类,而不是正确的包版本)

新(classNameWithAttribute)

new 有一个奇怪但有记录的特征,它允许您在类名上设置 package 属性,这实际上工作得很好(即没有上面提到的问题),如果有点冗长的话:

name = 'className'
attr(name, 'package') = 'packageName'
new(name)

尽管如此,您没有理由不能将其变成可重用的函数:

new = function(cls, pkg, ...){
attr(cls, 'package') = pkg
methods::new(cls, ...)
}
new('className', 'packageName')

好的包装设计

当然,如果 S4 类的包装器提供以下两种机制之一,则所有这些都可以避免:

导出 setClass()

setClass() 具有副作用(将类存储在注册表中)和返回值(类生成器函数)。因此,如果打包者选择在他们的 NAMESPACE 中存储和导出返回值,我们可以稍后访问它:

# In package "myPackage"
myClass = setClass('myClass')

# In package's NAMESPACE
export(myClass)

# In user's script
new(myPackage::myClass)

例如,您可以使用之前的相同测试包对此进行测试:

install.packages('lookupTable')
new(lookupTable::lookupTable)

导出构造函数

这是生物导体的标准做法。他们定义了一个与类本身同名的构造函数。然后,您可以使用 :: 访问构造函数,并调用它而不是 new:

install.packages("BiocManager")
BiocManager::install("IRanges")

new("IRanges")
# Equivalent to
IRanges::IRanges()

关于来自不同包的同名 R S4 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60726607/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com