Tidyverse风格的数据录入

Author

Lee

Published

March 31, 2025

1 读取单个文件

library(tidyverse)
library(readxl)
df <- read_csv("D:/Myblog/datas/read_datas/S1班学生成绩.csv")
df
# A tibble: 4 × 6
  班级  姓名   性别   语文  数学  英语
  <chr> <chr>  <chr> <dbl> <dbl> <dbl>
1 六1班 何娜   女       87    92    79
2 六1班 黄才菊 女       95    77    75
3 六1班 陈芳妹 女       79    87    66
4 六1班 陈学勤 男       82    79    66

2 读取多个文件

这是一个重要的功能。实际应用中,我们经常会遇到需要读取多个表格文件的情况。如果一个一个读取,需要重复写多行代码(多次复制粘贴操作),与代码书写原则相悖(不要重复书写相同的代码两次以上)。这时我们需要用到purrr中的map()系列函数。

读取多个文件有如下几个基本步骤:

  1. 列出目录中需要读取的文档-list.files(),list.files()函数有是三个主要参数:
  • 第一个参数path,为文件的路径。
  • 第二个参数pattern,为一个正则表达式,用来选择需要读取的文档名。通常我们用到的"[.]xlsx$"[.]csv$,用于查找具有特定扩展名的所有文件。
  • 第三个参数full.names,为一个逻辑值,决定了在输出的结果中是否包含完整的目录名(通常我们设置为TRUE)。
  1. 利用循环机制批量读取
  2. 将读取的结果合并为一个数据框

2.1 读取多个xlsx文件

# 列出目录中所有xlsx文件
files <- list.files(
  path = "D:/Myblog/datas/read_datas/",
  pattern = "[.]xlsx$",
  full.names = TRUE,
  recursive = TRUE
)
files
 [1] "D:/Myblog/datas/read_datas/61grades.xlsx"                  
 [2] "D:/Myblog/datas/read_datas/62grades.xlsx"                  
 [3] "D:/Myblog/datas/read_datas/63grades.xlsx"                  
 [4] "D:/Myblog/datas/read_datas/64grades.xlsx"                  
 [5] "D:/Myblog/datas/read_datas/65grades.xlsx"                  
 [6] "D:/Myblog/datas/read_datas/wirte_datas/setosa.xlsx"        
 [7] "D:/Myblog/datas/read_datas/wirte_datas/versicolor.xlsx"    
 [8] "D:/Myblog/datas/read_datas/wirte_datas/virginica.xlsx"     
 [9] "D:/Myblog/datas/read_datas/wirte_datas/学生成绩_wirte.xlsx"
[10] "D:/Myblog/datas/read_datas/学生成绩.xlsx"                  
# 使用map函数批量读取
dfs_1 <- map_dfr(set_names(files), read_xlsx, .id = "file_name")
dfs_1
# A tibble: 1,412 × 12
   班级  姓名   性别   语文  数学  英语 Sepal.Length Sepal.Width Petal.Length
   <chr> <chr>  <chr> <dbl> <dbl> <dbl>        <dbl>       <dbl>        <dbl>
 1 61班  何娜   女       87    92    79           NA          NA           NA
 2 61班  黄才菊 女       95    77    75           NA          NA           NA
 3 61班  陈芳妹 女       79    87    66           NA          NA           NA
 4 61班  陈学勤 男       82    79    66           NA          NA           NA
 5 六2班 黄祖娜 女       94    88    75           NA          NA           NA
 6 六2班 徐雅琦 女       92    86    72           NA          NA           NA
 7 六2班 徐达政 男       90    86    72           NA          NA           NA
 8 六2班 陈华健 男       92    84    70           NA          NA           NA
 9 六3班 江佳欣 女       80    69    75           NA          NA           NA
10 六3班 何诗婷 女       76    53    72           NA          NA           NA
# ℹ 1,402 more rows
# ℹ 3 more variables: Petal.Width <dbl>, Species <chr>, file_name <chr>

2.2 读取一个xlsx中的多个sheet

path <- "D:/Myblog/datas/read_datas/学生成绩.xlsx"
dfs_2 <- map_dfr(
  set_names(excel_sheets(path)),
  \(x) read_excel(path, sheet = x),
  .id = "sheet"
)
dfs_2
# A tibble: 20 × 7
   sheet  班级  姓名   性别   语文  数学  英语
   <chr>  <chr> <chr>  <chr> <dbl> <dbl> <dbl>
 1 六一班 六1班 何娜   女       87    92    79
 2 六一班 六1班 黄才菊 女       95    77    75
 3 六一班 六1班 陈芳妹 女       79    87    66
 4 六一班 六1班 陈学勤 男       82    79    66
 5 六二班 六2班 黄祖娜 女       94    88    75
 6 六二班 六2班 徐雅琦 女       92    86    72
 7 六二班 六2班 徐达政 男       90    86    72
 8 六二班 六2班 陈华健 男       92    84    70
 9 六三班 六3班 江佳欣 女       80    69    75
10 六三班 六3班 何诗婷 女       76    53    72
11 六三班 六3班 林可莉 女       72    52    72
12 六三班 六3班 雷  帆 男       78    56    66
13 五一班 五1班 周婵   女       92    94    77
14 五一班 五1班 李小龄 男       90    87    69
15 五一班 五1班 陈丽丽 女       87    93    61
16 五一班 五1班 杨昌晟 男       84    85    64
17 五二班 五2班 符苡榕 女       85    89    76
18 五二班 五2班 陆曼   女       88    84    69
19 五二班 五2班 容唐   女       83    71    56
20 五二班 五2班 蒙丽梅 女       72    72    64

3 写出文件

写出文件通常是数据分析的最后一步。我们可以使用write_csv()write_xlsx()等函数将数据写入文件。与读取文件类似,写出文件也可以批量进行。

# 写出到一个文件
library(writexl)
write_xlsx(dfs_1, "D:/Myblog/datas/read_datas/wirte_datas/学生成绩_wirte.xlsx")

# 批量写出到多个文件-iris数据为例
df_iris <- iris |>
  group_split(Species)
## 准备文件名
files <- paste0(
  "D:/Myblog/datas/read_datas/wirte_datas/",
  levels(iris$Species),
  ".xlsx"
)
## 批量写出
walk2(df_iris, files, write_xlsx)