第六章:for 循环与 while 循环语句

本章将学习 R 语言的循环语句。循环是编程中用来重复执行一段代码的核心机制------当你需要对一组数据做同样的操作时,手动写 N 遍显然不现实,循环帮你自动搞定。

一、为什么需要循环?

假设你要输出 1 到 5 的数字,不写循环是这样的:

r 复制代码
print(1)
print(2)
print(3)
print(4)
print(5)

如果要求输出 1 到 100 呢?手动写 100 行?

循环让你用几行代码搞定重复任务。

二、for 循环(最常用)

for 循环会遍历一个序列,对序列中的每个元素执行一次代码块。

语法:

r 复制代码
for (变量 in 序列) {
  循环体(重复执行的代码)
}

1. 基础示例:输出 1 到 5

r 复制代码
for (i in 1:5) {
  print(i)
}

运行结果:

txt 复制代码
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5

1:5 是 R 中生成连续整数的快捷写法,表示从 1 到 5 的序列。

2. 遍历向量

r 复制代码
fruits <- c("苹果", "香蕉", "橘子", "葡萄")

for (fruit in fruits) {
  print(paste("我喜欢吃", fruit))
}

运行结果:

txt 复制代码
[1] "我喜欢吃 苹果"
[1] "我喜欢吃 香蕉"
[1] "我喜欢吃 橘子"
[1] "我喜欢吃 葡萄"

3. 带索引的遍历

当你需要同时知道位置(索引)和值时:

r 复制代码
fruits <- c("苹果", "香蕉", "橘子")

for (i in 1:length(fruits)) {
  print(paste("第", i, "个水果是:", fruits[i]))
}

运行结果:

txt 复制代码
[1] "第 1 个水果是: 苹果"
[1] "第 2 个水果是: 香蕉"
[1] "第 3 个水果是: 橘子"

length() 函数返回向量的长度,1:length(fruits) 生成 1, 2, 3 的索引序列。

4. 循环累加(求 1+2+...+100)

r 复制代码
total <- 0

for (i in 1:100) {
  total <- total + i
}

print(paste("1到100的和是:", total))

运行结果:

txt 复制代码
[1] "1到100的和是: 5050"

三、while 循环(条件驱动)

while 循环在条件为 TRUE 时一直执行,适合不确定循环次数的场景。

语法:

r 复制代码
while (条件) {
  循环体
  # 注意:必须有让条件变为 FALSE 的操作,否则死循环!
}

1. 基础示例

r 复制代码
count <- 1

while (count <= 5) {
  print(paste("当前计数:", count))
  count <- count + 1  # 每次加1,最终让条件不成立
}

运行结果:

txt 复制代码
[1] "当前计数: 1"
[1] "当前计数: 2"
[1] "当前计数: 3"
[1] "当前计数: 4"
[1] "当前计数: 5"

2. 实用示例:猜数字

r 复制代码
target <- 7
guess <- 0

while (guess != target) {
  guess <- guess + 1
  print(paste("尝试猜:", guess))
}

print("猜对了!")

运行结果:

txt 复制代码
[1] "尝试猜: 1"
[1] "尝试猜: 2"
[1] "尝试猜: 3"
[1] "尝试猜: 4"
[1] "尝试猜: 5"
[1] "尝试猜: 6"
[1] "尝试猜: 7"
[1] "猜对了!"

四、repeat 循环(了解即可)

R 还有一个 repeat 循环,它没有条件判断 ,必须用 break 手动跳出:

r 复制代码
x <- 1

repeat {
  print(x)
  x <- x + 1
  if (x > 5) {
    break  # 跳出循环
  }
}

运行结果:

txt 复制代码
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5

五、循环控制:break 与 next

1. break:提前结束整个循环

r 复制代码
for (i in 1:10) {
  if (i == 5) {
    break  # 到5就停
  }
  print(i)
}

运行结果:

txt 复制代码
[1] 1
[1] 2
[1] 3
[1] 4

2. next:跳过当前轮,继续下一轮

r 复制代码
for (i in 1:6) {
  if (i == 3) {
    next  # 跳过3
  }
  print(i)
}

运行结果:

txt 复制代码
[1] 1
[1] 2
[1] 4
[1] 5
[1] 6

六、嵌套循环(循环里套循环)

当需要处理二维数据(如矩阵)时会用到嵌套循环:

r 复制代码
# 打印九九乘法表(部分)
for (i in 1:3) {
  for (j in 1:i) {
    cat(i, "×", j, "=", i * j, "\t")
  }
  cat("\n")  # 换行
}

运行结果:

txt 复制代码
1 × 1 = 1
2 × 1 = 2 	2 × 2 = 4
3 × 1 = 3 	3 × 2 = 6 	3 × 3 = 9

cat() 函数和 print() 类似,但不会输出 [1] 前缀,更适合拼接输出。\t 是制表符,\n 是换行符。

七、for 与 while 怎么选?

场景 推荐用
已知循环次数(如遍历 1 到 100) for
遍历向量/列表中的每个元素 for
不确定循环次数,靠条件终止 while
满足条件前一直执行 while

90% 的情况用 for 就够了,while 适合特殊场景。

八、综合实战练习(可直接复制运行)

r 复制代码
# ==============================
# R 综合练习:循环应用
# 场景:学生成绩统计
# ==============================

# 1. 定义一组成绩
scores <- c(92, 85, 67, 73, 58, 95, 88, 41, 76, 81)

# 2. 用 for 循环统计及格与不及格人数
pass_count <- 0
fail_count <- 0

for (score in scores) {
  if (score >= 60) {
    pass_count <- pass_count + 1
  } else {
    fail_count <- fail_count + 1
  }
}

print(paste("及格人数:", pass_count))
print(paste("不及格人数:", fail_count))

# 3. 用 while 循环找到第一个不及格的成绩
index <- 1
while (scores[index] >= 60) {
  index <- index + 1
}
print(paste("第一个不及格的成绩是第", index, "个:", scores[index]))

# 4. 用 for + next 跳过无效成绩(负数),计算有效成绩平均分
mixed_scores <- c(90, 85, -1, 72, -5, 88, 60)
valid_total <- 0
valid_count <- 0

for (s in mixed_scores) {
  if (s < 0) {
    next  # 跳过负数
  }
  valid_total <- valid_total + s
  valid_count <- valid_count + 1
}

average <- valid_total / valid_count
print(paste("有效成绩平均分:", round(average, 2)))

运行结果:

txt 复制代码
[1] "及格人数: 8"
[1] "不及格人数: 2"
[1] "第一个不及格的成绩是第 5 个: 58"
[1] "有效成绩平均分: 79"
相关推荐
段一凡-华北理工大学13 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
Ljwuhe13 小时前
C++——多态
开发语言·c++
心平气和量大福大14 小时前
C#-WPF-Window主窗体
开发语言·c#·wpf
从零开始的代码生活_15 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
云小逸15 小时前
【C++ 第七阶段:模板、泛型编程与工程综合详解】
开发语言·c++
GIS阵地16 小时前
QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)
开发语言·前端·c++·qt·qgis
yaoxin52112316 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python
groundhappy17 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
小钻风336618 小时前
Spring Boot 文件上传详解:深入理解 MultipartFile 的使用与原理
java·开发语言
qq_4523962318 小时前
第二篇:《Go 开发环境搭建:SDK、IDE、Module 与 Hello World》
开发语言·ide·golang