第十三章:R 读取 txt、csv 表格数据

数据分析的第一步永远是读取数据。真实数据通常存储在 CSV、TXT 等文件中,本章将学习如何用 R 读取外部数据文件,以及如何把分析结果导出保存。

一、数据文件常见格式

格式 扩展名 特点
CSV .csv 逗号分隔,最通用的表格格式
TXT .txt 制表符或自定义分隔符
Excel .xlsx 需要额外包(如 readxl)

本章重点:CSV 和 TXT,因为 R 内置函数就能处理,无需安装任何包。

二、准备工作:设置工作目录

R 需要知道去哪个文件夹找文件。

1. 查看当前工作目录

r 复制代码
getwd()

运行结果:

txt 复制代码
[1] "d:/develop/code/R"

2. 设置工作目录

setwd 适合小型数据分析项目。大型项目(推荐用 here 包)

r 复制代码
# ❌ 坏写法(换电脑就找不到)
setwd("d:/develop/code/R/data")

# ✅ 好写法(项目相对路径)
setwd("data")

建议:把数据文件放在工作目录下,读取时直接写文件名即可,不用写完整路径。

三、读取 CSV 文件

1. 先创建一个示例 CSV 文件

运行以下代码,自动生成一个练习用的 CSV 文件:

r 复制代码
# 设置到你放数据文件的目录
setwd("data")

# 创建示例数据并保存为 CSV
students <- data.frame(
  name    = c("张三", "李四", "王五", "赵六", "孙七"),
  gender  = c("男", "女", "男", "男", "女"),
  math    = c(92, 88, 76, 65, 95),
  chinese = c(85, 72, 95, 58, 88),
  english = c(78, 90, 82, 70, 92),
  stringsAsFactors = FALSE
)

write.csv(students, "students.csv", row.names = FALSE)
print("已生成 students.csv")

2. 用 read.csv() 读取

r 复制代码
# 设置到你放数据文件的目录
setwd("data")

# 读取 CSV 文件
df <- read.csv("students.csv", stringsAsFactors = FALSE)

print(df)

运行结果:

txt 复制代码
  name gender math chinese english
1 张三     男   92      85      78
2 李四     女   88      72      90
3 王五     男   76      95      82
4 赵六     男   65      58      70
5 孙七     女   95      88      92

3. read.csv() 常用参数

r 复制代码
# 设置到你放数据文件的目录
setwd("data")

df <- read.csv(
  "students.csv",
  header = TRUE,                # 第一行是否为列名(默认 TRUE)
  stringsAsFactors = FALSE,     # 不自动将字符串转为因子
  encoding = "UTF-8",           # 编码(中文文件常用)
  sep = ","                     # 分隔符(CSV 默认逗号)
)

4. 读取中文 CSV 的常见问题

如果读出来是乱码,尝试指定编码:

r 复制代码
# 方法1:指定 UTF-8 编码
df <- read.csv("students.csv", fileEncoding = "UTF-8", stringsAsFactors = FALSE)

# 方法2:如果是 Windows 下 GBK 编码
df <- read.csv("students.csv", fileEncoding = "GBK", stringsAsFactors = FALSE)

四、读取 TXT 文件

1. 创建示例 TXT 文件

r 复制代码
# 创建制表符分隔的 TXT 文件
students <- data.frame(
  name    = c("张三", "李四", "王五"),
  math    = c(92, 88, 76),
  chinese = c(85, 72, 95),
  stringsAsFactors = FALSE
)

write.table(students, "students.txt", sep = "\t", row.names = FALSE, quote = FALSE)
print("已生成 students.txt")

2. 用 read.table() 读取

r 复制代码
# 读取制表符分隔的 TXT
df <- read.table("students.txt", header = TRUE, sep = "\t", stringsAsFactors = FALSE)

print(df)

运行结果:

txt 复制代码
  name math chinese
1 张三   92      85
2 李四   88      72
3 王五   76      95

3. read.csv vs read.table

函数 默认分隔符 适用场景
read.csv() 逗号 , CSV 文件
read.table() 空格/制表符 TXT 文件,灵活指定分隔符

实际上 read.csv()read.table() 的简化版:

r 复制代码
# 这两行等价
read.csv("data.csv")
read.table("data.csv", header = TRUE, sep = ",")

4. 读取其他分隔符的文件

r 复制代码
# 分号分隔
df <- read.table("data.csv", header = TRUE, sep = ";", stringsAsFactors = FALSE)

# 空格分隔
df <- read.table("data.txt", header = TRUE, sep = " ", stringsAsFactors = FALSE)

# 竖线分隔
df <- read.table("data.txt", header = TRUE, sep = "|", stringsAsFactors = FALSE)

五、读取后检查数据

养成读取后立即检查的好习惯:

r 复制代码
df <- read.csv("students.csv", stringsAsFactors = FALSE)

# 第一步:看前几行
head(df)

# 第二步:看结构
str(df)

# 第三步:看维度
dim(df)
nrow(df)
ncol(df)

# 第四步:看列名
names(df)

# 第五步:快速统计
summary(df)

六、导出数据

1. 导出为 CSV

r 复制代码
df <- data.frame(
  name = c("张三", "李四", "王五"),
  math = c(92, 88, 76),
  stringsAsFactors = FALSE
)

# 导出 CSV(不保存行号)
write.csv(df, "output.csv", row.names = FALSE)

2. 导出为 TXT

r 复制代码
# 导出制表符分隔的 TXT
write.table(df, "output.txt", sep = "\t", row.names = FALSE, quote = FALSE)

3. 导出参数说明

r 复制代码
write.csv(
  df,
  "output.csv",
  row.names = FALSE,     # 不保存行号(通常不需要)
  quote = FALSE,         # 不给字符串加引号
  fileEncoding = "UTF-8" # 指定编码
)

七、读写完整流程示例

r 复制代码
# ==============================
# 完整流程:读取 → 处理 → 导出
# ==============================

# 1. 创建原始数据并保存
raw <- data.frame(
  name    = c("张三", "李四", "王五", "赵六", "孙七"),
  gender  = c("男", "女", "男", "男", "女"),
  math    = c(92, 88, 76, 65, 95),
  chinese = c(85, 72, 95, 58, 88),
  english = c(78, 90, 82, 70, 92),
  stringsAsFactors = FALSE
)
write.csv(raw, "scores_raw.csv", row.names = FALSE)

# 2. 读取数据
df <- read.csv("scores_raw.csv", stringsAsFactors = FALSE)

# 3. 数据处理:计算总分、平均分、等级
df$total   <- df$math + df$chinese + df$english
df$average <- round(df$total / 3, 1)
df$grade   <- ifelse(df$average >= 90, "优秀",
              ifelse(df$average >= 80, "良好",
              ifelse(df$average >= 60, "及格", "不及格")))

# 4. 导出处理后的数据
write.csv(df, "scores_result.csv", row.names = FALSE)
print("处理完成,已导出 scores_result.csv")

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

r 复制代码
# ==============================
# R 综合练习:文件读写实战
# 场景:从原始数据到分析报告
# ==============================

# 1. 创建模拟数据(模拟从外部获取的原始数据)
set.seed(42)
n <- 15

raw_data <- data.frame(
  id      = 1:n,
  name    = paste0("学生", sprintf("%02d", 1:n)),
  gender  = sample(c("男", "女"), n, replace = TRUE),
  class   = sample(c("A班", "B班"), n, replace = TRUE),
  math    = round(runif(n, 40, 100)),
  chinese = round(runif(n, 40, 100)),
  english = round(runif(n, 40, 100)),
  stringsAsFactors = FALSE
)

# 故意加入几个缺失值
raw_data$math[3]    <- NA
raw_data$english[7] <- NA

# 2. 保存原始数据
write.csv(raw_data, "exam_raw.csv", row.names = FALSE)
print("原始数据已保存到 exam_raw.csv")

# 3. 重新读取(模拟从文件开始工作流)
df <- read.csv("exam_raw.csv", stringsAsFactors = FALSE)

print("=== 读取成功,前5行预览 ===")
print(head(df))
print(paste("共", nrow(df), "行", ncol(df), "列"))

# 4. 数据检查
print("=== 数据结构 ===")
str(df)

print("=== 缺失值检查 ===")
for (col in names(df)) {
  na_count <- sum(is.na(df[[col]]))
  if (na_count > 0) {
    print(paste(col, "列有", na_count, "个缺失值"))
  }
}

# 5. 处理缺失值(用该科平均分填充)
df$math[is.na(df$math)]    <- round(mean(df$math, na.rm = TRUE))
df$english[is.na(df$english)] <- round(mean(df$english, na.rm = TRUE))

# 6. 计算分析指标
df$total   <- df$math + df$chinese + df$english
df$average <- round(df$total / 3, 1)
df$grade   <- ifelse(df$average >= 90, "优秀",
              ifelse(df$average >= 80, "良好",
              ifelse(df$average >= 60, "及格", "不及格")))

# 7. 排序
df <- df[order(df$total, decreasing = TRUE), ]
df$rank <- 1:nrow(df)

# 8. 导出最终结果
write.csv(df, "exam_result.csv", row.names = FALSE)
print("分析结果已导出到 exam_result.csv")

# 9. 输出摘要
print("=== 最终结果 ===")
print(df[, c("rank", "name", "class", "math", "chinese", "english", "total", "average", "grade")])

# 10. 按班级汇总导出
class_summary <- aggregate(
  cbind(math, chinese, english, total) ~ class,
  data = df,
  FUN = mean
)
class_summary$math    <- round(class_summary$math, 1)
class_summary$chinese <- round(class_summary$chinese, 1)
class_summary$english <- round(class_summary$english, 1)
class_summary$total   <- round(class_summary$total, 1)

write.csv(class_summary, "exam_class_summary.csv", row.names = FALSE)
print("=== 班级汇总 ===")
print(class_summary)

运行结果:

txt 复制代码
[1] "原始数据已保存到 exam_raw.csv"
[1] "=== 读取成功,前5行预览 ==="
  id   name gender class math chinese english
1  1 学生01     男   A班   84      97      81
2  2 学生02     男   B班   89      93      99
3  3 学生03     男   B班   NA      78      86
4  4 学生04     男   B班   81      98      74
5  5 学生05     女   B班   40      77      91
6  6 学生06     女   A班   90      60      51
[1] "共 15 行 7 列"
[1] "=== 数据结构 ==="
'data.frame':	15 obs. of  7 variables:
 $ id     : int  1 2 3 4 5 6 7 8 9 10 ...
 $ name   : chr  "学生01" "学生02" "学生03" "学生04" ...
 $ gender : chr  "男" "男" "男" "男" ...
 $ class  : chr  "A班" "B班" "B班" "B班" ...
 $ math   : int  84 89 NA 81 40 90 40 52 94 77 ...
 $ chinese: int  97 93 78 98 77 60 61 64 87 42 ...
 $ english: int  81 99 86 74 91 51 NA 90 82 54 ...
[1] "=== 缺失值检查 ==="
[1] "math 列有 1 个缺失值"
[1] "english 列有 1 个缺失值"
[1] "分析结果已导出到 exam_result.csv"
[1] "=== 最终结果 ==="
   rank   name class math chinese english total average  grade
2     1 学生02   B班   89      93      99   281    93.7   优秀
9     2 学生09   A班   94      87      82   263    87.7   良好
1     3 学生01   A班   84      97      81   262    87.3   良好
4     4 学生04   B班   81      98      74   253    84.3   良好
3     5 学生03   B班   70      78      86   234    78.0   及格
14    6 学生14   A班   98      56      69   223    74.3   及格
5     7 学生05   B班   40      77      91   208    69.3   及格
8     8 学生08   A班   52      64      90   206    68.7   及格
6     9 学生06   A班   90      60      51   201    67.0   及格
12   10 学生12   A班   66      81      48   195    65.0   及格
11   11 学生11   B班   63      85      43   191    63.7   及格
15   12 学生15   A班   66      71      52   189    63.0   及格
10   13 学生10   A班   77      42      54   173    57.7 不及格
7    14 学生07   A班   40      61      70   171    57.0 不及格
13   15 学生13   A班   42      50      53   145    48.3 不及格
[1] "=== 班级汇总 ==="
  class math chinese english total
1   A班 70.9    66.9    65.0 202.8
2   B班 68.6    86.2    78.6 233.4
相关推荐
Biomamba生信基地11 小时前
R语言scRNA-seq去RNA污染手册
r语言·单细胞测序·scrna-seq
Omics Pro12 小时前
全流程可重复!R语言脂质组学:原始数据→功能解析
开发语言·人工智能·深度学习·语言模型·r语言·excel·知识图谱
雁迟1 天前
第八章:矩阵与数组操作
线性代数·矩阵·r语言
雁迟1 天前
第六章:for 循环与 while 循环语句
开发语言·r语言
雁迟1 天前
第七章:R 向量用法(最核心数据结构)
开发语言·数据结构·r语言
雁迟1 天前
第九章:列表 List 数据类型
数据结构·r语言
雁迟1 天前
第十章:数据框 DataFrame(数据分析主力)
数据挖掘·数据分析·r语言
雁迟1 天前
第五章:条件判断与分支语句
开发语言·r语言
陳土2 天前
R语言jiebaR包使用摘要
开发语言·r语言