R S3 类

S3 类是 R 编程语言中最流行的类。

它简单易实现,因此 R 中预定义的大多数类都属于此类型。


在 R 中创建 S3 类和对象

创建 S3 类

首先我们创建一个包含各种组件的列表,然后使用 class() 函数创建一个类。例如,

# create a list with required components
employee1 <- list(name = "Peter", age = 21, role = "Developer")

# form class of employee1 list and 
# name the class appropriately
class(employee1) <- "Employee_Info"

在这里,我们首先创建了一个名为 employee1 的列表,其中包含所需的组件。

然后我们使用 class(employee1) 形成了 employee1 的类,并将该类命名为 Employee_Info

现在我们可以创建这个类的一个对象。

创建 S3 对象

S3 对象本质上是一个列表,其类属性被分配了一些名称。我们使用列表的名称来创建和调用我们创建的对象。

要创建和调用上面类的对象,我们只需使用列表名称 employee1。例如,

# create and call an object
employee1

在这里,我们已成功创建并调用了 Employee_Info 类的一个对象。


示例:R S3 类

# create a list with required components
employee1 <- list(name = "Peter", age = 21, role = "Developer")

# form class of employee1 list and 
# name the class appropriately
class(employee1) <- "Employee_Info"

# create and call an object
employee1

输出

$name
[1] "Peter"

$age
[1] 21

$role
[1] "Developer"

attr(,"class")
[1] "Employee_Info"

在上面的示例中,我们创建了一个名为 employee1 的列表,其中包含三个组件。

这里,Employee_Info 是类的名称。为了创建这个类的一个对象,我们将 employee1 列表传递到 class() 中。

最后,我们创建了 Employee_Info 类的一个对象,并将其命名为 employee1


R 中的 S3 泛型函数和方法

泛型函数由多个函数组成,这些函数为不同类型实现相同的操作。

在上面的示例中,我们简单地使用对象名称来打印类属性。在交互模式下,单独写入名称将使用 print() 函数打印它。

# create and call object without print()
employee1

# create and call object with print()
print(employee1)

在这里,两种情况的输出都将相同

此外,我们可以将 print()向量数据框因子 等一起使用,它们会根据所属的类以不同的方式打印。

print() 如何知道如何打印这些种类繁多的不同对象?

答案是,print() 是一个泛型函数。实际上,它包含许多方法的集合。

您可以使用以下方式检查所有这些方法

# to display all available methods
methods(print)

输出

[1] print.Arima*                                        
[2] print.AsIs                                          
[3] print.Bibtex*
...
...
[184] print.xgettext*                                     
[185] print.xngettext*                                    
[186] print.xtabs*

在这里,methods() 函数将显示 print 的所有可用方法,共 186 个。

我们可以在上面的列表中看到 print.factorprint.data.frame 等方法。

当我们对因子调用 print() 时,它会分派给 print.factor()。在这里,我们可以观察到方法名称的形式是 generic_name.class_name()

这就是 R 如何根据类来确定要调用哪个方法。

打印我们的 Employee_Info 类对象会查找 print.Employee_Info() 形式的方法,但没有这种形式的方法。

那么,我们的 Employee_Info 类对象调用了哪个方法呢?

它调用了 print.default()。这是在没有找到其他匹配项时调用的备用方法。泛型函数都有一个默认方法。


在 R 中编写自己的方法

由于我们上面讨论过没有 print.Employee_Info() 方法。我们将尝试自己实现 print.Employee_Info() 方法。

print.Employee_Info <- function(obj) {
cat(obj$name, "\n")
cat(obj$age, "years old\n")
cat("Role:", obj$role, "\n")
}

在这里,我们创建了一个名为 print.Employee_Info() 的方法。我们将 obj 作为参数传递。

我们使用了 obj$ 来获取 Employee_Info 类的 nameagerole 属性的值。

现在,每当我们 print() 一个 Employee_Info 类的对象时,就会调用此方法。

# create a list with required components
employee1 <- list(name = "Peter", age = 21, role = "Developer")

# form class of employee1 list and 
# name the class appropriately
class(employee1) <- "Employee_Info"

print.Employee_Info <- function(obj) {
cat(obj$name, "\n")
cat(obj$age, "years old\n")
cat("Role:", obj$role, "\n")
}

print(employee1)

输出

Peter 
21 years old
Role: Developer

在这里,每当我们 print() 一个 Employee_Info 类的对象时,都会调用 print.Employee_Info()

我们也可以像这样使用 print.Employee_Info() 方法

print.Employee_Info(employee1)

输出将相同。


你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战