【问题标题】:Vectorize an S4 class in R在 R 中矢量化 S4 类
【发布时间】:2018-10-01 04:05:51
【问题描述】:

我在定义数组之类的类时遇到了一些麻烦,因为它们是完全类型化的(尽可能在 R 中)。 我的例子:我想定义一个类Avector,它应该包含类A的任意数量的元素。

# Define the base class
setClass("A", representation(x = "numeric"))

# Some magic needed ????
setClass("Avector", ???)

# In the end one should be able to use it as follows:
a1 <- new("A", x = 1)
a2 <- new("A", x = 2)
X <- new("Avector", c(a1, a2))

我知道在 R 中不可能有一个对象向量。所以我猜它会存储在一种“类型化”列表中。 我找到了一些解决方案,但我对此并不满意:

# Define the vectorized class
setClass(
  "Avector", 
  representation(X = "list"), 
  valididty = function(.Object)) {
    if (all(sapply(.Object@X, function(x) class(x) == "A")))
      TRUE
    else
      "'Avector' must be a list of elements in the class 'A'"
  }
)
# Define a method to subscript the elements inside of the vector
setMethod(
  "[", signature(x = "Avector", i = "ANY", j = "ANY"),
  function(x, i, j, ...) x@X[[i]]
)
# Test the class
a1 <- new("A", x = 1)
a2 <- new("A", x = 2)
avec <- new("Avector", X = list(a1, a2))
# Retrieve the element in index i
avec[i]

这种方法对我来说更像是一种 hack。有没有办法在 R 中以规范的方式做到这一点,而无需手动进行这种类型检查和索引方法?

编辑: 如果类A 不是由原子槽组成,这也应该成立。例如在这种情况下:

setClass("A", representation(x = "data.frame"))

我很高兴得到帮助 :) 干杯, 阿德里安

【问题讨论】:

    标签: arrays r class vector s4


    【解决方案1】:

    答案在某种程度上取决于您要完成的工作,并且在您的用例中可能会也可能不会。 S4 的工作方式是对象应该是高级别的,以避免过多的开销。

    通常,有必要让 slots 成为向量。你不能在 R 中定义新的原子类型。所以在你的玩具示例中而不是调用

    avec <- new("Avector", X = list(a1, a2))
    

    你打电话

    avec <- new("A", x = c(1, 2))
    

    这可能需要其他槽(以前是向量)变成数组,例如。

    如果您迫切需要原子类型,那么您可以覆盖现有类型之一。例如,我认为 bit64 包就是这样做的。本质上,您所做的是创建一个继承自 numeric 的新类,然后为新类编写许多替代所有默认方法的方法。

    【讨论】:

    • 感谢您的帮助...我的玩具示例有一个重大缺陷,因为“A”类不需要包含原子插槽(我编辑了我的问题。)。所以,如果我说对了,这个问题就没有简单的解决方案(除了覆盖现有类型)。 一般情况下,槽必须是向量是什么意思?这是否意味着使用我的 hacky 解决方案 setClass("Avector", representation(X = "list")) 是不可接受的?
    • 没关系——一个列表仍然是一个向量(如果它的对象类型不是原子的,这是必要的)
    猜你喜欢
    • 1970-01-01
    • 2016-05-30
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    相关资源
    最近更新 更多