我一直在开发一个S4类,它本质上是一个带有一点额外信息的data.frame。出于这个问题的目的,这个类的“额外”特征是无关紧要的。重要的是该类包含一个存储在其中一个插槽中的data.frame对象。 (我将data.frame放在一个插槽中,而不是将其命名为超类,因为我发现包含data.frames的S4类由于某种原因将data.frames简化为列表。)
这是一个基本的例子:
setClass('tmp_class', slots = c(df = 'data.frame'))
test_object <- new('tmp_class', df = data.frame(Num = 1:10, Let = letters[1:10]))
现在我想要做的是使应用于此类对象的任何函数应用于插槽@df中的data.frame。编写特定函数的方法很容易,例如:
setMethod('dim', signature = c(x = 'tmp_class'), function(x) dim(x@df))
但我只限于我能想到的功能,而且用户发明的任何功能都不起作用。
编写一种包装器/闭包来修改一个函数来处理我的类是一件很简单的事情,如下所示:
tmp_classize <- function(func){
function(tmp, ...){ func(tmp@df, ...) }
}
所以,不是为colnames()或ncol()编写方法,而是运行:
tmp_classize(colnames)(test_object)
或
tmp_classize(ncol)(test_object)
但我想做的是以某种方式在我自己的任何函数上唤起我的“tmp_classize”函数。我无法弄清楚该怎么做。我想如果可以某种方式调用带有“tmp_class”类的输入签名的“通用方法”,然后使用sys.function()来获取被调用的实际函数,也许我可以使某些东西工作,但是A)那里是递归问题B)我不知道如何称这种“通用”方法。在我看来,解决方案,如果它存在,可能需要非标准的评估,我宁愿避免,但可能会在必要时使用。
谢谢!
P.S。我意识到这项任务可能是不明智/糟糕的编程技术,我可能永远不会在包中实现它。我仍然很想知道是否有可能。
P.P.S。我也对应用于S3类的相同想法感兴趣!
答案 0 :(得分:0)
原则上,您可以为您的班级和classUnion
创建一个data.frame
,并为您的班级编写处理所有读写data.frames
的方法的方法。如$
,[
,dim()
,<-
等等。然后,当其他函数试图将您的新类用作data.frame
时,将有一些方法可以使用它。这在John Chambers&#34; Software for Data Analysis&#34;从第375页开始。那说这个系统可能很难实现。
更简单的系统可能只是为您的data.frame
添加额外的属性,并提供您需要的额外信息。例如:
x<-data.frame(a=1:3,b=4:6)
attr(x,"Info")<-"Extra info I need"
attributes(x)$Info
[1] "Extra info I need"
这不像S4
类那样优雅,但会执行data.frame
所做的所有事情。我怀疑那些熟悉S3
课程的人可以改进这个想法。
答案 1 :(得分:0)
最简单的解决方案是让您的班级包含 data.frame
,而不是将其作为其中一个广告位。例如,这里是带有时间戳的data.frame
:
setclass(
"timestampedDF",
slots=c(timestamp="POSIXt"),
contains="data.frame"
)
现在,适用于data.frame
的所有功能(例如head
)将自动适用于timestampedDF
个对象。如果您需要访问&#34;数据框部分&#34;,那么它将保存在隐藏的广告位object@.Data
中。