向量(Vector)是 R 语言中最核心、最基础的数据结构。R 语言的设计哲学就是"一切皆向量"------哪怕一个数字,R 也把它当作长度为 1 的向量。掌握向量,就掌握了 R 的半壁江山。
一、什么是向量?
向量就是一个有序的、同一类型的元素集合。可以理解为一排格子,每个格子里放一个数据:
[92, 85, 67, 73] ← 数值向量
["苹果", "香蕉"] ← 字符向量
[TRUE, FALSE] ← 逻辑向量
关键特点:
- 所有元素必须是同一类型(数值、字符、逻辑)
- 从 1 开始编号(不是 0!)
二、创建向量
1. 用 c() 创建(最常用)
c() 是 combine(合并)的缩写:
r
# 数值向量
scores <- c(92, 85, 67, 73)
print(scores)
# 字符向量
fruits <- c("苹果", "香蕉", "橘子")
print(fruits)
# 逻辑向量
flags <- c(TRUE, FALSE, TRUE)
print(flags)
运行结果:
txt
[1] 92 85 67 73
[1] "苹果" "香蕉" "橘子"
[1] TRUE FALSE TRUE
2. 用 : 生成连续整数序列
r
nums <- 1:10
print(nums)
运行结果:
txt
[1] 1 2 3 4 5 6 7 8 9 10
3. 用 seq() 生成自定义序列
r
# 从1到10,步长为2
s1 <- seq(1, 10, by = 2)
print(s1)
# 从0到1,分成5等份
s2 <- seq(0, 1, length.out = 5)
print(s2)
运行结果:
txt
[1] 1 3 5 7 9
[1] 0.00 0.25 0.50 0.75 1.00
4. 用 rep() 重复元素
r
# 把数字3重复5次
r1 <- rep(3, times = 5)
print(r1)
# 重复一个向量
r2 <- rep(c(1, 2, 3), times = 3)
print(r2)
# 每个元素重复(逐个重复)
r3 <- rep(c(1, 2, 3), each = 2)
print(r3)
运行结果:
txt
[1] 3 3 3 3 3
[1] 1 2 3 1 2 3 1 2 3
[1] 1 1 2 2 3 3
三、访问向量元素(索引)
1. 用 [索引] 取单个元素
注意:R 的索引从 1 开始,不是 0!
r
scores <- c(92, 85, 67, 73)
print(scores[1]) # 第1个
print(scores[3]) # 第3个
运行结果:
txt
[1] 92
[1] 67
2. 用 c() 取多个元素
r
scores <- c(92, 85, 67, 73)
print(scores[c(1, 3)]) # 取第1和第3个
print(scores[1:3]) # 取第1到第3个
运行结果:
txt
[1] 92 67
[1] 92 85 67
3. 用负索引排除元素
r
scores <- c(92, 85, 67, 73)
print(scores[-1]) # 去掉第1个
print(scores[c(-2, -4)]) # 去掉第2和第4个
运行结果:
txt
[1] 85 67 73
[1] 92 67
4. 用逻辑向量筛选
r
scores <- c(92, 85, 67, 73)
# 筛选大于70的成绩
print(scores[scores > 70])
运行结果:
txt
[1] 92 85 73
5. 用名称索引
r
scores <- c(92, 85, 67)
names(scores) <- c("数学", "语文", "英语")
print(scores["数学"])
运行结果:
txt
数学
92
四、修改向量元素
r
scores <- c(92, 85, 67, 73)
# 修改单个元素
scores[3] <- 88
print(scores)
# 修改多个元素
scores[c(1, 2)] <- c(95, 90)
print(scores)
运行结果:
txt
[1] 92 85 88 73
[1] 95 90 88 73
五、向量运算(向量化操作)
R 最强大的特性之一:运算自动应用到每个元素,不需要写循环。
1. 向量与数值运算
r
scores <- c(60, 70, 80, 90)
# 每个元素加5
print(scores + 5)
# 每个元素乘2
print(scores * 2)
# 每个元素平方
print(scores^2)
运行结果:
txt
[1] 65 75 85 95
[1] 120 140 160 180
[1] 3600 4900 6400 8100
2. 向量与向量运算
r
a <- c(1, 2, 3)
b <- c(10, 20, 30)
print(a + b) # 对应元素相加
print(a * b) # 对应元素相乘
运行结果:
txt
[1] 11 22 33
[1] 10 40 90
3. 向量与逻辑判断
r
scores <- c(92, 55, 73, 48, 85)
print(scores > 60)
print(scores[scores >= 60])
运行结果:
txt
[1] TRUE FALSE TRUE FALSE TRUE
[1] 92 73 85
六、向量常用函数
r
scores <- c(92, 55, 73, 48, 85)
length(scores) # 元素个数
sum(scores) # 求和
mean(scores) # 平均值
max(scores) # 最大值
min(scores) # 最小值
sort(scores) # 排序(升序)
sort(scores, decreasing = TRUE) # 降序排序
range(scores) # 最大值和最小值
which.max(scores) # 最大值的索引位置
which.min(scores) # 最小值的索引位置
逐个测试:
r
scores <- c(92, 55, 73, 48, 85)
print(paste("个数:", length(scores)))
print(paste("总和:", sum(scores)))
print(paste("平均:", mean(scores)))
print(paste("最高:", max(scores)))
print(paste("最低:", min(scores)))
print(paste("升序:", paste(sort(scores), collapse = ", ")))
print(paste("降序:", paste(sort(scores, decreasing = TRUE), collapse = ", ")))
print(paste("最高分是第", which.max(scores), "个"))
print(paste("最低分是第", which.min(scores), "个"))
运行结果:
txt
[1] "个数: 5"
[1] "总和: 353"
[1] "平均: 70.6"
[1] "最高: 92"
[1] "最低: 48"
[1] "升序: 48, 55, 73, 85, 92"
[1] "降序: 92, 85, 73, 55, 48"
[1] "最高分是第 1 个"
[1] "最低分是第 4 个"
七、向量类型与转换
1. 查看类型
r
x <- c(1, 2, 3)
class(x) # "numeric"
y <- c("a", "b")
class(y) # "character"
z <- c(TRUE, FALSE)
class(z) # "logical"
2. 类型转换
r
# 数值 → 字符
as.character(c(1, 2, 3)) # "1" "2" "3"
# 字符 → 数值
as.numeric(c("1.5", "2.3")) # 1.5 2.3
# 逻辑 → 数值(TRUE=1, FALSE=0)
as.numeric(c(TRUE, FALSE)) # 1 0
3. 类型自动转换规则
当向量中混合了不同类型,R 会自动转换:
r
# 数值 + 字符 → 全部变字符
mixed <- c(1, "hello", 3)
print(mixed) # "1" "hello" "3"
class(mixed) # "character"
# 数值 + 逻辑 → 全部变数值
mixed2 <- c(1, TRUE, 3)
print(mixed2) # 1 1 3
八、向量追加与删除
r
nums <- c(1, 2, 3)
# 追加元素
nums <- c(nums, 4, 5)
print(nums)
# 在指定位置插入
nums <- append(nums, 99, after = 2)
print(nums)
# 删除元素(用负索引重新赋值)
nums <- nums[-3] # 删除第3个元素
print(nums)
运行结果:
txt
[1] 1 2 3 4 5
[1] 1 2 99 3 4 5
[1] 1 2 3 4 5
九、综合实战练习(可直接复制运行)
r
# ==============================
# R 综合练习:向量操作实战
# 场景:班级成绩分析系统
# ==============================
# 1. 创建成绩向量(带名称)
scores <- c(92, 85, 67, 73, 58, 95, 88, 41, 76, 81)
names(scores) <- c("张三", "李四", "王五", "赵六", "孙七",
"周八", "吴九", "郑十", "钱十一", "陈十二")
# 2. 基本统计
print("=== 基本统计 ===")
print(paste("班级人数:", length(scores)))
print(paste("班级总分:", sum(scores)))
print(paste("平均分:", round(mean(scores), 2)))
print(paste("最高分:", max(scores)))
print(paste("最低分:", min(scores)))
# 3. 找到最高分和最低分的学生
print("=== 极值学生 ===")
print(paste("最高分:", names(scores[which.max(scores)]), scores[which.max(scores)], "分"))
print(paste("最低分:", names(scores[which.min(scores)]), scores[which.min(scores)], "分"))
# 4. 分档统计
print("=== 成绩分档 ===")
excellent <- scores[scores >= 90]
good <- scores[scores >= 80 & scores < 90]
pass <- scores[scores >= 60 & scores < 80]
fail <- scores[scores < 60]
print(paste("优秀(≥90):", length(excellent), "人"))
print(paste("良好(80-89):", length(good), "人"))
print(paste("及格(60-79):", length(pass), "人"))
print(paste("不及格(<60):", length(fail), "人"))
# 5. 成绩排名(降序)
print("=== 成绩排名 ===")
ranked <- sort(scores, decreasing = TRUE)
for (i in 1:length(ranked)) {
print(paste("第", i, "名:", names(ranked[i]), ranked[i], "分"))
}
# 6. 每人成绩与平均分的差距
print("=== 与平均分差距 ===")
avg <- mean(scores)
for (name in names(scores)) {
diff <- scores[name] - avg
if (diff >= 0) {
print(paste(name, ":", scores[name], "分,高出平均", round(diff, 1), "分"))
} else {
print(paste(name, ":", scores[name], "分,低于平均", round(abs(diff), 1), "分"))
}
}
运行结果:
txt
[1] "=== 基本统计 ==="
[1] "班级人数: 10"
[1] "班级总分: 756"
[1] "平均分: 75.6"
[1] "最高分: 95"
[1] "最低分: 41"
[1] "=== 极值学生 ==="
[1] "最高分: 周八 95 分"
[1] "最低分: 郑十 41 分"
[1] "=== 成绩分档 ==="
[1] "优秀(≥90): 2 人"
[1] "良好(80-89): 3 人"
[1] "及格(60-79): 3 人"
[1] "不及格(<60): 2 人"
[1] "=== 成绩排名 ==="
[1] "第 1 名: 周八 95 分"
[1] "第 2 名: 张三 92 分"
[1] "第 3 名: 吴九 88 分"
[1] "第 4 名: 李四 85 分"
[1] "第 5 名: 陈十二 81 分"
[1] "第 6 名: 钱十一 76 分"
[1] "第 7 名: 赵六 73 分"
[1] "第 8 名: 王五 67 分"
[1] "第 9 名: 孙七 58 分"
[1] "第 10 名: 郑十 41 分"
[1] "=== 与平均分差距 ==="
[1] "张三 : 92 分,高出平均 16.4 分"
[1] "李四 : 85 分,高出平均 9.4 分"
[1] "王五 : 67 分,低于平均 8.6 分"
[1] "赵六 : 73 分,低于平均 2.6 分"
[1] "孙七 : 58 分,低于平均 17.6 分"
[1] "周八 : 95 分,高出平均 19.4 分"
[1] "吴九 : 88 分,高出平均 12.4 分"
[1] "郑十 : 41 分,低于平均 34.6 分"
[1] "钱十一 : 76 分,高出平均 0.4 分"
[1] "陈十二 : 81 分,高出平均 5.4 分"