【问题标题】:Abstract types in RR中的抽象类型
【发布时间】:2016-01-30 16:39:28
【问题描述】:

我想在 R 中创建类,假设它是一个人的 S4 类。例如

setClass("Person", slots = list(name = "character", mood = "myMoodType"))

现在我想创建myMoodType 是一个抽象类型,它只能接受三个值“快乐”、“悲伤”和“未知”。

我知道我可以使用 S4 类的有效性来做到这一点,并将心情作为字符类型,并通过验证提供的字符串是我列出的三个选项之一来检查有效性。但我想知道我是否可以定义一个抽象类型,比如在 julia 中,例如

abstract myMoodType
type Happy   <: myMoodType             end
type Sad     <: myMoodType             end
type Unknown <: myMoodType             end

在 R 中处理这个问题的正确方法是什么?

【问题讨论】:

  • 在我看来,两种语言的更好解决方案是将myMoodType 声明为Enum,具有Happy 、Sad 和Unknown 3 个值
  • 你嫁给了 S4 吗?一般而言,这不是一个经过深思熟虑的 OOP 机制——我建议使用 S3 或 R6 来代替,并忘记 S4 曾经存在过。也就是说,S3 和 R6 在这方面都不会真正为您提供帮助,而且实际上大多数语言中的大多数 OOP 实现都不支持您想要实现的目标(称为 sum types)。
  • 感谢您的参考。我只是以 S4 为例。
  • 考虑您是否真的想要一个名为“未知”的可能级别,因为 R 已经使用 NA 来标记缺失的信息。
  • @Backlin ... 和NULL,和NaN,和NA_character_,和NA_real_,和...... ;-)

标签: r julia s4 abstract-data-type


【解决方案1】:

这可能不是 R 最强大和最流畅的功能之一,但您可以通过以下方式解决它。如需更多信息,请参阅the documentation 或Advanced R chapter on S4。

首先设置 Person 类,将情绪表示为一个因素,并将其链接到检查其级别的验证函数。

check_person <- function(object) {
    if(identical(levels(object@mood), c("Happy", "Sad", "Unknown"))){
        return(TRUE)
    } else {
        return("Invalid mood.")
    }
}

setClass("Person",
         representation(name = "character", mood = "factor"),
         prototype = list(name = NA_character_,
                          mood = factor(NA, c("Happy", "Sad", "Unknown"))),
         validity = check_person)

但是,使用new 创建新实例有点麻烦,因为我们每次都必须写出所有级别:

john <- new("Person", name="John", mood=factor("Happy", levels=c("Happy", "Sad", "Unknown")))
lucy <- new("Person", name="Lucy", mood=factor("Sad", levels=c("Happy", "Sad", "Unknown")))

否则会报错:

new("Person", name="Eve", mood="Unknown")
Error in validObject(.Object) : 
  invalid class “Person” object: invalid object for slot "mood" in class "Person":
  got class "character", should be or extend class "factor"

要解决这个问题,您可以创建自己的构造函数:

new_person <- function(name, mood){
    new("Person", name = name, mood = factor(mood, levels = c("Happy", "Sad", "Unknown")))
}
new_person("Eve", "Unknown")
An object of class "Person"
Slot "name":
[1] "Eve"

Slot "mood":
[1] Unknown
Levels: Happy Sad Unknown

【讨论】:

  • 我认为 OP 明确表示这不是他们想要的解决方案,他们希望“情绪”是 sum 类型集中的特定类类型。
  • @KonradRudolph 这个答案涵盖了我想要的功能。也许我应该在这方面编辑我的问题。
  • @Gumeo 呃,如果这个答案是你想要的,只需将其标记为已接受。我认为这就足够了。
  • @KonradRudolph 你说得对,我的解决方案不符合 OP 的要求,但我认为这是在 R 中获得所需功能的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
相关资源
最近更新 更多