R S3类
- 创建 S3 类和对象:在 R 中,S3 类通过创建一个列表并为其指定一个类名来创建,如
class(employee1) <- "Employee_Info"
。S3 对象本质上是一个带有类属性的列表,通过列表名称创建和调用。 - 泛型函数和方法:
print()
是一个泛型函数,包含多个方法来处理不同类型的对象。使用methods(print)
可查看所有可用的print
方法。对于自定义类(如Employee_Info
),如果没有特定的打印方法,则会调用print.default()
。 - 自定义方法:可以为特定类编写自定义方法,例如
print.Employee_Info()
,用于定义该类对象的打印行为。此方法在调用print()
时自动应用于Employee_Info
类的对象。
S3 类是 R 编程语言中最受欢迎的类。
它简单易实现,因此 R 中预定义的大多数类都是这种类型。
在 R 中创建 S3 类和对象
创建 S3 类
首先我们创建一个包含各种组件的列表,然后使用 class()
函数创建一个类。例如,
# 创建一个包含所需组件的列表
employee1 <- list(name = "Peter", age = 21, role = "Developer")
# 形成 employee1 列表的类并
# 合理命名该类
class(employee1) <- "Employee_Info"
这里,我们首先创建了一个名为 employee1
的列表,包含所需的组件。
然后我们使用 class(employee1)
形成了 employee1
的一个类,并将这个类命名为 Employee_Info
。
现在我们可以创建这个类的一个对象。
创建 S3 对象
一个 S3 对象基本上是一个列表,其类属性被赋予了一些名称。我们使用列表的名称来创建和调用我们创建的对象。
要创建和调用上述类的对象,我们简单地使用列表名称 employee1
。例如,
# 创建并调用一个对象
employee1
这里,我们已经成功地创建并调用了 Employee_Info
类的一个对象。
示例:R S3 类
# 创建一个包含所需组件的列表
employee1 <- list(name = "Peter", age = 21, role = "Developer")
# 形成 employee1 列表的类并
# 合理命名该类
class(employee1) <- "Employee_Info"
# 创建并调用一个对象
employee1
输出
$name
[1] "Peter"
$age
[1] 21
$role
[1] "Developer"
attr(,"class")
[1] "Employee_Info"
在上述示例中,我们创建了一个名为 employee1
、包含三个组件的列表。
这里,Employee_Info
是类的名称。为了创建这个类的一个对象,我们在 class()
内传递了 employee1
列表。
最后,我们创建了一个 Employee_Info
类的对象,并调用了名为 employee1
的对象。
R 中的 S3 泛型函数和方法
一个泛型函数由实现对不同类型相同操作的多个函数组成。
在上述示例中,我们只是使用对象名称打印类属性。在交互模式下,单独写下名称会使用 print()
函数打印它。
# 不使用 print() 创建并调用对象
employee1
# 使用 print() 创建并调用对象
print(employee1)
这里,在两种情况下,输出将是相同的
此外,我们可以使用 print()
与 向量、数据框、因子 等,它们会根据所属的类别以不同方式打印。
print()
函数如何知道如何打印这些外观不同的对象?
答案是,print()
是一 个泛型函数。实际上,它包含了许多方法。
您可以使用以下方法检查所有这些方法:
# 显示所有可用的方法
methods(print)
输出
[1] print.Arima*
[2] print.AsIs
[3] print.Bibtex*
...
...
[184] print.xgettext*
[185] print.xngettext*
[186] print.xtabs*
这里,methods()
函数将显示 print
的所有可用方法,共 186 个。
我们可以在上面的列表中看到像 print.factor
和 print.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
类的 name
、age
和 role
属性的值。
现在每当我们对 Employee_Info
类的对象使用 print()
时,都会调用这个方法。
# 创建一个包含所需组件的列表
employee1 <- list(name = "Peter", age = 21, role = "Developer")
# 形成 employee1 列表的类并
# 合理命名该类
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
这里,每当我们对 Employee_Info
类的对象使用 print()
时,都会调用 print.Employee_Info()