【问题标题】:Copy the structure of an R object with slots (but not the data)复制带有槽的 R 对象的结构(但不复制数据)
【发布时间】:2021-05-18 07:11:15
【问题描述】:

我想复制一个 R 对象的结构,它是一个带槽的列表。

是否可以这样做以生成没有数据的副本 R 对象,或者将所有数据替换为 NA?

下面是一个极其简化的 R 列表对象,以槽为例:

setClass("Car",representation=representation(
   price = "numeric",
   numberDoors="numeric",
   typeEngine="character",
   mileage="numeric"
))
aCar <- new("Car",price=20000,numberDoors=4,typeEngine="V6",mileage=143)
obj <- list(test1="testing",test2=aCar)

用 NA 手动替换每个插槽是行不通的,因为这是一个简化版本...有什么想法吗? 谢谢!

【问题讨论】:

  • lists 没有插槽,所以我不确定你想要什么,lapply(obj, function(x) if (isS4(x)) new(class(x)) else NA)?
  • 我的列表似乎包含插槽,如上例所示(除非我没有使用正确的术语)... 2 $ 列表: chr "testing" $ :Formal class 'Car ' [package ".GlobalEnv"] 有 4 个插槽 .. ..@ price : num 20000 .. ..@ numberDoors: num 4 .. ..@ typeEngine : chr "V6" .. ..@ mileage : num 143 但是您的建议似乎可以解决问题 - 谢谢!

标签: r


【解决方案1】:

可以编写一个copy 方法来制作副本,然后将槽设置为NA。但由于仅分配 NA 并不容易,因此可以通过类联合明确允许逻辑:

## numeric cannot contain just NA
setClassUnion("numeric_or_NA", c("numeric", "logical"))
setClassUnion("character_or_NA", c("character", "logical"))

setClass("Car",representation=representation(
  price = "numeric_or_NA",
  numberDoors="numeric_or_NA",
  typeEngine="character_or_NA",
  mileage="numeric_or_NA"
))

setGeneric("copy", function(obj, ...) standardGeneric("copy"))

setMethod("copy", "Car",
  function(obj, ...) {
    for (s in slotNames(class(obj))) slot(obj, s) <- NA
    obj        
  }
)

aCar <- new("Car",price=20000,numberDoors=4,typeEngine="V6",mileage=143)
obj <- list(test1="testing",test2=aCar)
otherCar <- copy(aCar)
str(otherCar)

编辑

另一种方法是检查插槽的类并将NA 转换为正确的类型:

setClass("Car",representation=representation(
  price = "numeric",
  numberDoors="numeric",
  typeEngine="character",
  mileage="numeric"
))

setGeneric("copy", function(obj, ...) standardGeneric("copy"))

setMethod("copy", "Car",
          function(obj, ...) {
            s  <- getSlots(class(obj))
            nm <- slotNames(class(obj))
            for (i in 1:length(s)) {
              slot(obj, nm[i]) <- as(NA, s[i])
            }
            obj        
          }
)

aCar <- new("Car", price=20000, numberDoors=4, typeEngine="V6", mileage=143)
obj <- list(test1="testing",test2=aCar)
otherCar <- copy(aCar)
str(otherCar)

最后一个问题:为什么要复制对象而不是使用类中的new 实例化它?

还要注意,除了 S4 之外,R 还具有其他几个基于原型(无类)的类系统。

【讨论】:

  • 我不是在创建对象,而是在导入它们。列表 r 对象(带插槽)是预先制作的,我正在导入工作区,以便可以使用数据创建图。每个物种/年有一个这些对象。但是,某些物种/年份对象不可用,因此我想从不同年份复制该物种的对象。对象的“架构”必须相同,但没有数据(或 NA)。
  • 但我认为您应该有权访问类定义?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多