我试图从包XML扩展S3对象。我对S3类的理解是R寻找正确的函数来应用类向量中的每个类,从左到右,如果没有为当前类定义函数,则移动到下一个类。例如,使用lm
对象:
ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2, 10, 20, labels = c("Ctl","Trt"))
weight <- c(ctl, trt)
x <- lm(weight ~ group)
pryr::otype(x)
[1]&#34; S3&#34;
class(x) <- append("MyLMClass", class(x)) # adding class
print.MyLMClass <- function(x) cat("this is from MyLMClass") # overriding print
x
这是来自MyLMClass
summary()
未定义MyLMClass
,但在x
上调用它确实有效,因为R
会转到下一个类lm
:
summary(x)
呼叫: lm(公式=重量〜组)
残差: Min 1Q Median 3Q Max -1.0710 -0.4938 0.0685 0.2462 1.3690
系数:
估计标准。误差t值Pr(&gt; | t |)
(拦截)5.0320 0.2202 22.850 9.55e-15 ***
(等)
但这对XML对象不起作用:
library(XML)
someXML <- newXMLNode("a")
newXMLNode("g", 3, parent = someXML)
newXMLNode("c", 5, parent = someXML)
someXML
<a>
<g>3</g>
<c>5</c>
</a>
pryr::otype(someXML)
[1] "S3"
getNodeSet(someXML, "/a/c/")[[1]]
给出了:
<c>5</c>
但是一旦我添加了一个新类,没有任何作用,甚至不打印:
> class(someXML) <- append("MyClass", class(someXML))
> someXML
Error in as.vector(x, "character") :
cannot coerce type 'externalptr' to vector of type 'character'
> getNodeSet(someXML,"/a/c")[[1]]
Error in as(doc, "XMLInternalDocument") :
no method or default for coercing “MyClass” to “XMLInternalDocument”
我希望能够扩展XML对象,以便:
我怎样才能做到这一点?
(似乎getNodeSet()
不是S3泛型,这可能解释了为什么它不适用于新类。)
编辑:
将someXML
投射到XMLDocument
会使getNodeSet()
工作:
someXML <- newXMLNode("a")
newXMLNode("g", 3, parent = someXML)
newXMLNode("c", 5, parent = someXML)
someXML <- newXMLDoc(someXML) # <== that's new
class(someXML) <- append("MyClass", class(someXML))
class(someXML) <- append("MyClass2", class(someXML))
getNodeSet(someXML,"/a/c")[[1]]
<c>5</c>
但print()
仍然无效:
someXML
Error in as.vector(x, "character") :
cannot coerce type 'externalptr' to vector of type 'character'