5

假设我有这样的功能:

myf = function(x) {
res = dostuff(x)
res # this is a data.frame
}

我想做一些特别的事情res,例如,我想做一些通用的函数,比如print.myf, summary.myf, ... ,所以我可以继续给它一个类:

myf = function(x) {
res = dostuff(x)
class(res) = 'myf'
res
}

但是这样我就不能再将它用作 data.frame 了。

4

2 回答 2

4

是的,我的标准(简单)示例是

R> now <- Sys.time()
R> class(now)
[1] "POSIXct" "POSIXt" 
R> class(as.POSIXlt(now))
[1] "POSIXlt" "POSIXt" 
R> 

这也是专业提示使用 测试inherits("someClass")而不是测试结果背后的原因class(obj)=="someClass"

于 2013-10-12T15:34:32.263 回答
3

这是一个例子rle。该rle函数创建 a list,但它没有 class list,因此像这样的方法as.data.frame不会“开箱即用”。因此,我将最后一行更改为添加"list"为类之一。

x <- c(1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3)

rle2 <- function (x)
{
  if (!is.vector(x) && !is.list(x))
    stop("'x' must be an atomic vector")
  n <- length(x)
  if (n == 0L)
    return(structure(list(lengths = integer(), values = x),
                     class = "rle"))
  y <- x[-1L] != x[-n]
  i <- c(which(y | is.na(y)), n)

  ## THE FOLLOWING IS FROM THE BASE RLE. NOTICE ONLY ONE CLASS...
  # structure(list(lengths = diff(c(0L, i)), values = x[i]), 
  #  class = "rle")

  structure(list(lengths = diff(c(0L, i)), values = x[i]),
            class = c("rle", "list"))
}

如您所见,我只是更改了class. 其余功能相同。

rle(x)
# Run Length Encoding
#   lengths: int [1:3] 4 3 7
#   values : num [1:3] 1 2 3
data.frame(rle(x))
# Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
#   cannot coerce class ""rle"" to a data.frame
rle2(x)
# Run Length Encoding
#   lengths: int [1:3] 4 3 7
#   values : num [1:3] 1 2 3
data.frame(rle2(x))
#   lengths values
# 1       4      1
# 2       3      2
# 3       7      3

当然,如果我们知道这一点,我们也可以明确指定我们的方法,如果我们知道存在一个方法:

as.data.frame.list(rle(x))
#   lengths values
# 1       4      1
# 2       3      2
# 3       7      3
于 2013-10-12T15:40:24.083 回答