在一个继承自data.frame的S4对象上应用terms.formula

4

我正在尝试创建一个从数据帧继承的新类:

> setClass('new.frame',
    representation(colour='character'),
    contains = 'data.frame')

这是该类的一个实例,用于测试:

> test_data = data.frame(cbind(runif(5), runif(5)))
> names(test_data) = c('X', 'Y')
> test_frame = new('new.frame', test_data, colour='red')

仅仅为了确保它看起来没问题...

> data.frame
Object of class "new.frame"
          X         Y
1 0.8766306 0.4741213
2 0.1221508 0.5117665
3 0.4838761 0.4973627
4 0.7858294 0.4064749
5 0.5147703 0.9135304
Slot "colour":
[1] "red"

... 并确保继承有效

> is.data.frame(test_frame)
[1] TRUE
> getClass(class(test_frame))
Class "new.frame" [in ".GlobalEnv"]

Slots:

Name:                .Data              colour               names
Class:                list           character           character

Name:            row.names            .S3Class
Class: data.frameRowLabels           character

Extends: 
Class "data.frame", directly
Class "list", by class "data.frame", distance 2
Class "oldClass", by class "data.frame", distance 2
Class "vector", by class "data.frame", distance 3

当我尝试利用数据框的属性时,遇到了以下问题:

> terms.formula(Y ~ X, data = test_frame)
Error in terms.formula(Y ~ X, data = test_frame) : 
  'data' argument is of the wrong type

我可能错过了一些愚蠢的东西。如果是这样,请提前指出。

如果我对这个问题正确,有没有办法让terms.formula认识到我正在给它一个数据框?

1个回答

1

执行debug(terms.formula),然后运行terms.formula(Y ~ X, data = test_frame)会显示您的代码在引用代码块的第3和第4行失败:

if (!is.null(data) && !is.environment(data) && !is.data.frame(data)) 
    data <- as.data.frame(data, optional = TRUE)
terms <- .Internal(terms.formula(x, specials, data, keep.order, 
    allowDotAsName))

问题可能是调用.Internal(terms.formula())期望一个“普通的”data.frame,而实际上传递了一个new.frame类的对象。 作为解决方法,为什么不直接传递terms.formula()所期望的对象类型(一个未装饰的data.frame)呢?
以下是一种简单的方法:
terms.formula(Y ~ X, data = unclass(test_frame))
# Y ~ X
# attr(,"variables")
# list(Y, X)
# attr(,"factors")
#   X
# Y 0
# X 1
# attr(,"term.labels")
# [1] "X"
# attr(,"order")
# [1] 1
# attr(,"intercept")
# [1] 1
# attr(,"response")
# [1] 1
# attr(,".Environment")
# <environment: R_GlobalEnv>

我还没有敢尝试去追踪(或理解)sp包的工作原理,但是SpatialPointsDataFrame(或SpatialxxxDataFrame)可以很好地与terms.formula一起使用。 - mnel
2
@mnel -- 这是因为 SpatialPointsDataFrame 在上面引用代码块的第一行不通过 is.data.frame() 测试,从而触发调用 as.data.frame() (实际上是 as.data.frame.SpatialPointsDataFrame())。这将返回所需的诚实数据框架,因此对 .Internal(terms.formula()) 的调用正常工作。(如果你运行 library(sp); example(meuse); is.data.frame(meuse); class(as.data.frame(meuse)),你就可以看到这个过程是如何工作的。) - Josh O'Brien
太棒了。感谢Josh!也感谢mnel参与讨论! - Centzon Totochtin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接