使用参考类作为因子的级别

时间:2013-04-24 14:53:24

标签: r reference-class

有没有人有使用参考类作为因素水平的经验?这是我在我的一个软件包中为data.frame添加“类似外键”支持的目标中的一步。

我最终想要创建一个data.frame,它可以作为整数存储与因子相关的代码,但是这个因子的级别实际上是Reference Class对象,而不是通常使用的字符向量因子。我已经能够找到一些关于使用S4对象作为因子级别的信息,但这些技术似乎不适用于参考类。

例如,简单:

> myClass <- setRefClass("MyClass", fields=list(a="numeric", b="character"))
> myObj <- myClass$new(a=1, b="test")
> factor(myObj)
Error in unique.default(x) : unique() applies only to vectors
> as.character(myObj)
Error in as.vector(x, "character") : 
  cannot coerce type 'environment' to vector of type 'character'
> as.character.MyClass <- function(x){ x$b }
> as.character(myObj)
[1] "test"
> factor(myObj)
Error in unique.default(x) : unique() applies only to vectors
>
> unique.MyClass <- function (x, incomparables = FALSE, ...) { unique(as.character(x)) }
> factor(myObj)
Error in as.vector(x, mode) : invalid 'mode' argument
> traceback()
2: as.vector(exclude, typeof(x))
1: factor(myObj)

似乎没有任何工作。看起来,在我最好的情况下,我可以到factor()分析exclude参数的行:

exclude <- as.vector(exclude, typeof(x))

此时一切都崩溃了,因为我不允许创建“S4”类型的向量。

如何解决这个问题或者 - 更好的 - 以data.frame友好的方式将整数映射到Reference Class对象的任何想法都将非常感激!


编辑:回应@ Aaron的问题:

这里的简单解决方案是在data.frame中存储整数,然后维护一个单独的列表/ data.frame,负责将这些ID映射到其他一些数据(例如Reference Class对象)。这将保留所有必要的数据来完成我的需要,但对我来说不那么优雅,原因如下:

  1. 我正在设想一个解决方案,允许我打印出Reference Class对象本身的某些部分,而不是ID。例如,如果我将员工ID(整数)映射到“员工”类,我希望我的data.frame打印员工的姓名,而不是他们的ID。
  2. 我希望能够直接从data.frame中提取对象。就像as.character(myDataFrame$someColumn)给我那个列的标签一样(假设它是一个因子),而不是实际存储在data.frame中的基础整数。
  3. 同样,如果有更好的方法,我对这个问题的替代解决方案非常开放!

1 个答案:

答案 0 :(得分:1)

我认为这可以通过使用必要的方法创建一个新类,例如myFactor来完成; format似乎是您在数据框中打印所需的那个;您可以轻松添加print或您选择的其他方法。我最熟悉S3方法,所以这就是我在这里所做的。

在这里,我为format类设置了引用类和myFactor函数。

myClass <- setRefClass("MyClass", fields=list(a="numeric", b="character"))
format.myFactor <- function(obj, ...) {
  n <- sapply(levels(obj), function(x) x[["b"]])
  n[obj]
}

这里我创建了两个新的引用对象,并将它们用作我的新myFactor对象的级别。

myObj <- myClass$new(a=1, b="test")
myObj2 <- myClass$new(a=4, b="testagain")
foo <- structure(c(2,1,2), levels=c(myObj, myObj2), class=c("myFactor","numeric"))
d <- data.frame(x=foo)

然后很好地打印。

> d
          x
1 testagain
2      test
3 testagain