S3 R语言数据类型6:S3系统与原子向量

S3 R语言数据类型6:S3系统与原子向量

在 R 语言中,S3 向量的本质是:通过 S3 面向对象系统增强的原子向量。它们是基础原子向量(如数值型、字符型等)与 S3 类属性结合的结果,赋予向量领域特定的行为和语义。

1.面向对象编程(OOP)

There is an important difference in philosophy between S(and hence R) and the other main statistical systems. In S a statistical analysis is normally done as a series of steps, with intermediate results being stored in objects.

  • R语言中的面向对象编程(Object-Oriented Programming, OOP)是一种重要的编程范式,它将对象作为程序的基本单元,通过将数据和操作封装(encapsulate)在对象中,提高了代码的可读性、可维护性和可扩展性。
  • R语言支持多种面向对象编程模型,主要包括S3、S4和R6。

1.1 S3 模型

  • S3是R语言中最简单、最灵活的面向对象模型。

  • 它基于泛型函数(generic functions)的概念,通过UseMethod()函数来实现方法的调度。

  • S3模型的实现方式相对简单,但缺乏严格的类定义和类型检查。

  • 泛型函数(generic function)是一种编程范式,它允许我们为不同的数据类型编写相同的函数接口。

  • 泛型函数的工作原理是:它们会根据传入的实际参数类型调用相应的方法。这意味着你可以为不同的类或数据结构定义相同名称的函数,但是它们的行为取决于传入的对象类型。

  • 类和对象:在S3中,类是通过class()函数分配给对象的。例如,可以将一个列表分配为某个类的对象:

person <- list(name = "Alice", age = 30)  # 1. 创建基础列表
class(person) <- "Person"                 # 2. 添加类属性
  • 方法:S3中的方法是通过function.classname的形式命名的。例如,可以为print函数创建一个针对Person类的自定义方法:
print.Person <- function(p) {
  cat("Name:", p$name, "\n")    # 输出姓名
  cat("Age:", p$age, "\n")       # 输出年龄
}
person# 直接调用对象名(隐式调用 print)
Name: Alice 
Age: 30 

当调用print(person)时,R会根据person的类属性"Person"来选择并调用print.Person函数。

  • 继承:S3支持基于类的继承。例如,可以定义一个Student类继承自Person类,并添加新的属性或方法:
# 创建学生对象
student <- list(name = "Bob", age = 20, major = "Mathematics")

# 设置类层级:Student 继承自 Person
class(student) <- c("Student", "Person")

# 定义 Student 专属的打印方法
print.Student <- function(s) {
  print.Person(s)     # 调用父类方法
  cat("Major:", s$major, "\n")  # 添加子类专属信息
}

1.2 S4 模型

S4是R语言中更正式、更严格的面向对象模型。它提供了更严格的类定义和类型检查机制,适合用于大型软件项目。

1.3 R6 模型

R6是R语言中一个较新的面向对象模型,它提供了更接近传统OOP语言(如Python和Java)的特性,包括封装、继承和公有/私有方法。

关于面向对象的编程之后会更进一步学习……


2. 四个重要的 S3 向量

2.1 因子 factor

类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。

factor是一种只能包含预定义值的向量。它用于存储分类数据。
factor建立在整数向量之上,具有两个属性:一个 class 属性,值为“factor”,这使得它与普通的整数向量表现不同;以及 levels 属性,它定义了允许值的集合。

x <- factor(c("a", "b", "b", "a"))#创建因子 x
#factor()函数将其转换为因子类型,并自动提取唯一值作为水平(levels),默认按字母顺序排列。
x
  1. a
  2. b
  3. b
  4. a
Levels:
  1. 'a'
  2. 'b'
typeof(x)  #  检查数据类型:typeof(x)输出: b"integer"
attributes(x)#检查属性:attributes(x)

‘integer’

$levels
  1. 'a'
  2. 'b'
$class
'factor'
有序因子(ordered factor)
# 创建有序因子
grade <- ordered(c("b", "b", "a", "c"),  # 输入数据
                 levels = c("c", "b", "a")  # 显式定义水平顺序
)

# 输出结果
grade
  1. b
  2. b
  3. a
  4. c
Levels:
  1. 'c'
  2. 'b'
  3. 'a'

2.2 日期(日精度)Date

# 获取当前日期
today <- Sys.Date()
today
# 查看数据类型
typeof(today)
#> [1] "double"

# 查看对象属性
attributes(today)
#> $class
#> [1] "Date"

‘double’

$class = ‘Date’

# 将字符串转换为日期对象
# 所有 R 日期对象存储为 自 1970-01-01 起的天数(称为 Unix 纪元)
date <- as.Date("2025-08-01")

# 去除类属性查看原始数值
unclass(date)

20301

日期值通常以字符串的形式输入到R中,然后转化为以数值形式存储的日期变量。函数as.Date()用于执行这种转化。

2.3 日期时间(具有秒或亚秒精度)POSIXct

  • base R 提供了两种存储日期时间信息的方式,POSIXct 和 POSIXlt。
  • “POSIX” 是 Portable Operating System Interface 的缩写,它是一系列跨平台标准。
  • “ct” 代表日历时间(C 语言中的 time_t 类型),而“lt” 代表本地时间(C 语言中的 struct tm 类型)。
# 创建 POSIXct 时间对象
now_ct <- as.POSIXct("2025-08-01 22:00", tz = "UTC")
# 显示时间对象
now_ct
#> [1]   # ISO格式 + 时区

# 检查底层存储类型
typeof(now_ct)
#> [1] "double"  # 双精度浮点数

# 查看对象属性
attributes(now_ct)
#> $class
#> [1] "POSIXct" "POSIXt"   # 类属性
#> 
#> $tzone
#> [1] "UTC"      # 时区属性
[1] "2025-08-01 22:00:00 UTC"

‘double’

$class
  1. 'POSIXct'
  2. 'POSIXt'
$tzone
'UTC'
# 转换为北京时区
beijing_time <- structure(now_ct, tzone = "Asia/Shanghai")
beijing_time
[1] "2025-08-02 06:00:00 CST"

2.4 持续时间 difftime

  • 持续时间,表示日期或日期时间对之间的时间量,存储在 difftimes 中。
  • Difftimes 基于 doubles 构建,并具有一个units属性。
# 创建以周为单位的时间差
one_week_1 <- as.difftime(1, units = "weeks")
one_week_1
#> Time difference of 1 weeks

# 创建以天为单位的时间差
one_week_2 <- as.difftime(7, units = "days")
one_week_2
#> Time difference of 7 days

# 检查数据类型
typeof(one_week_1)  # "double"
typeof(one_week_2)  # "double"

# 查看对象属性
attributes(one_week_1)
#> $class
#> [1] "difftime"
#> 
#> $units
#> [1] "weeks"

attributes(one_week_2)
#> $class
#> [1] "difftime"
#> 
#> $units
#> [1] "days"
Time difference of 1 weeks



Time difference of 7 days

‘double’

‘double’

$class
'difftime'
$units
'weeks'
$class
'difftime'
$units
'days'

参考资料:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值