第七章:R 向量用法(最核心数据结构)

向量(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 分"
相关推荐
Achou.Wang1 小时前
Go语言并发编程中的死锁防范与破解之道
服务器·开发语言·golang
我命由我123451 小时前
Visual Studio - Visual Studio 注释快捷键
java·c语言·开发语言·c++·ide·java-ee·visual studio
子安柠1 小时前
深入理解 Go 反射:原理、实践与性能陷阱
开发语言·golang
yoyo_zzm1 小时前
ThinkPHP3.X:经典PHP框架的全面解析
开发语言·php
lemon_sjdk2 小时前
DecimalFormat
java·开发语言·python
Nontee2 小时前
一、Java 基础 面试题解答(72题)
java·开发语言
兰令水2 小时前
topcode【随机算法题】【2026.5.16打卡-java版本】
java·数据结构·算法
Shan12052 小时前
广度优先搜索之层序遍历
数据结构·算法·宽度优先
会开花的二叉树2 小时前
Qt信号槽这套机制
开发语言·qt