我正在为一类“个人识别号码”(pin)的S3方法和类属性而苦苦挣扎。 我有这个对象:
> pin <- structure(c("870407-9311", "560203-1234"),
+ class = c("pin", "character"))
有时我想将此pin
与data.frame中的其他数据结合使用。然后我可能会遇到R的回收规则的一些问题,例如:
> data.frame(a = 1:4, pin, stringsAsFactors = FALSE)
Error in data.frame(a = 1:4, pin, stringsAsFactors = FALSE) :
arguments imply differing number of rows: 4, 2
一种方法是跳过stringsAsFactors = FALSE
(以及之后的反应),例如:
> x <- data.frame(a = 1:4, pin)
> isfac <- sapply(x, is.factor)
> x[isfac] <- lapply(x[isfac], as.character)
这个解决方案的问题在于它有点棘手,而且感觉并不自然。
另一种方法是使用I
函数,例如:
> y <- data.frame(a = 1:4, I(pin), stringsAsFactors = FALSE)
这是非常正确但是:
> class(y$pin)
[1] "AsIs" "pin" "character"
额外的课程AsIs
在大多数情况下都可以,但在我想要定义自己的format.pin
方法时却没有,因为首先会找到format.AsIs
方法,因为它(相反)其他xxx.AsIs
方法)在内部不使用NextMethod
。
我或许可以通过以下方式覆盖format
函数:
format <- function(x, ...) {
if (is.pin(x)) format.pin(x, ...)
else base::format(x, ...)
}
但是,当使用Roxygen2时,我的format.pin
方法不再被识别为S3方法,而是作为独立函数,因此,export(format.pin)
而不是S3method(print,pin)
被写入NAMESPACE
文件。
我显然可以定义一个独立的pin_format
函数(不是方法)或尝试(反对推荐)手动编辑NAMESPACE
但我希望还有另一个(更好更自然) )解决这个问题的方法!