Skip to content

R - 向量

向量(Vectors)是 R 中最基础的数据结构。它们是共享相同数据类型的一系列元素。主要有两种类型的向量:

  • 原子向量 (Atomic vectors):最简单的类型,所有元素必须是同一类型。R 中有六种基本的原子向量类型:逻辑型 (logical)、整型 (integer)、双精度浮点型 (double)(通常称为数值型 numeric)、字符型 (character)、复数型 (complex) 和原始字节型 (raw)。
  • 列表 (Lists):递归向量,可以包含不同类型的元素,包括其他列表。

本教程重点介绍原子向量,它们是 R 中大多数数据分析的构建块。

创建向量最常用的方法是使用 c() 函数,它表示“组合(combine)”或“连接(concatenate)”。

# 一个数值向量(类型为 'double')
numeric_vector <- c(10.5, 5.2, 8.0, 15.1)
print(numeric_vector)
# 一个整型向量(注意 'L' 后缀)
integer_vector <- c(1L, 6L, 10L)
print(integer_vector)
# 一个字符向量
character_vector <- c("hello", "world", "R", "is", "fun")
print(character_vector)
# 一个逻辑向量
logical_vector <- c(TRUE, FALSE, TRUE, TRUE)
print(logical_vector)

执行上述代码后,会产生以下结果:

[1] 10.5 5.2 8.0 15.1
[1] 1 6 10
[1] "hello" "world" "R" "is" "fun"
[1] TRUE FALSE TRUE TRUE

向量类型强制转换 (Vector Coercion)

Section titled “向量类型强制转换 (Vector Coercion)”

由于原子向量的所有元素必须是相同类型,当你尝试组合不同类型时,R 会将元素**强制(coerce)**转换为最灵活的类型。其优先级从低到高依次为:

logical → integer → double → character

# 数值和逻辑值被强制转换为字符型
mixed_vector <- c("red", 5, TRUE, 12.5)
print(mixed_vector)
# 检查结果向量的类型
print(typeof(mixed_vector))

执行上述代码后,会产生以下结果:

[1] "red" "5" "TRUE" "12.5"
[1] "character"

对于数值向量,你可以使用 : 运算符或 seq() 函数轻松创建序列。

# 创建一个从5到13的序列(包含两端)
seq_colon <- 5:13
print(seq_colon)
# 使用 seq() 函数进行更精细的控制
# 增量为0.5
seq_by_step <- seq(from = 5, to = 9, by = 0.5)
print(seq_by_step)
# 创建一个指定长度的序列
seq_by_length <- seq(from = 0, to = 100, length.out = 5)
print(seq_by_length)

执行上述代码后,会产生以下结果:

[1] 5 6 7 8 9 10 11 12 13
[1] 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0
[1] 0 25 50 75 100

访问向量元素(子集选择 Subsetting)

Section titled “访问向量元素(子集选择 Subsetting)”

你可以使用方括号 [] 访问向量的元素。R 使用1-基于索引 (1-based indexing),这意味着第一个元素位于位置 1。

days_of_week <- c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
# 1. 位置索引: 访问第2个和第5个元素
subset_pos <- days_of_week[c(2, 5)]
print(subset_pos)
# 2. 逻辑索引: 访问满足条件的元素 (条件为TRUE)
# 获取除了周末之外的所有日期
work_days_mask <- c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)
subset_log <- days_of_week[work_days_mask]
print(subset_log)
# 逻辑索引的更实用示例
scores <- c(88, 92, 75, 99, 65)
passing_scores <- scores[scores > 80]
print(passing_scores)
# 3. 负索引: 排除特定位置的元素
# 获取除了星期日(位置1)和星期六(位置7)之外的所有日期
subset_neg <- days_of_week[c(-1, -7)]
print(subset_neg)

执行上述代码后,会产生以下结果:

[1] "Mon" "Thu"
[1] "Mon" "Tue" "Wed" "Thu" "Fri"
[1] 88 92 99
[1] "Mon" "Tue" "Wed" "Thu" "Fri"

R 是一种向量化语言 (vectorized language),这意味着操作是逐元素应用的。这效率极高,可以让你避免编写循环。

# 创建两个向量
v1 <- c(3, 8, 4, 5, 0, 11)
v2 <- c(4, 11, 0, 8, 1, 2)
# 向量加法
add_result <- v1 + v2
print(add_result)
# 向量乘法
multi_result <- v1 * v2
print(multi_result)
# 向量除法(注意:除以零的结果是 'Inf',即无穷大)
div_result <- v1 / v2
print(div_result)

执行上述代码后,会产生以下结果:

[1] 7 19 4 13 1 13
[1] 12 88 0 40 0 22
[1] 0.7500000 0.7272727 Inf 0.6250000 0.0000000 5.5000000

向量元素循环利用 (Vector Element Recycling)

Section titled “向量元素循环利用 (Vector Element Recycling)”

如果你对两个长度不等的向量执行操作,R 会**循环利用 (recycles)**较短向量的元素。如果较长向量的长度不是较短向量长度的倍数,R 会发出警告。

v1 <- c(3, 8, 4, 5, 0, 11) # 长度为 6
v2 <- c(4, 11) # 长度为 2
# v2 会被循环利用为 c(4, 11, 4, 11, 4, 11)
add_result <- v1 + v2
print(add_result)
# 带警告的示例
v3 <- c(1, 2, 3, 4, 5) # 长度为 5
v4 <- c(10, 20) # 长度为 2
# 这会产生一个警告,因为 5 不是 2 的倍数。
sub_result <- v3 - v4
print(sub_result)

执行上述代码后,会产生以下结果:

[1] 7 19 8 16 4 22
[1] -9 -18 -7 -16 -5
Warning message:
In v3 - v4 : longer object length is not a multiple of shorter object length

sort() 函数返回一个元素已排序的新向量。要获取用于排序原始向量的索引,请使用 order() 函数。

v <- c(3, 8, 4, 5, 0, 11, -9, 304)
# 升序排序
sort_result <- sort(v)
print(sort_result)
# 降序排序
revsort_result <- sort(v, decreasing = TRUE)
print(revsort_result)
# 字符向量排序(默认区分大小写)
v_char <- c("Red", "Blue", "yellow", "violet")
sort_char_result <- sort(v_char)
print(sort_char_result)
# 使用 order() 获取排序索引
order_indices <- order(v)
print(order_indices)
# 使用索引来排序原始向量
print(v[order_indices])

执行上述代码后,会产生以下结果:

[1] -9 0 3 4 5 8 11 304
[1] 304 11 8 5 4 3 0 -9
[1] "Blue" "Red" "violet" "yellow"
[1] 7 5 1 3 4 2 6 8
[1] -9 0 3 4 5 8 11 304