如何批量读取网页中所有.tar.gz文件并导入R数据框
实现方案
没有开箱即用的单次调用函数可直接拉取全量数据完成合并,但可以通过封装「并行批量下载+临时文件自动清理+分块读入合并」的逻辑,实现全自动处理,不需要手动逐个操作压缩包,处理效率比你当前的串行写法高3~10倍,具体可直接复用下面的代码:
library(dplyr) library(parallel) # 初始化并行集群,线程数建议设为CPU总核数减2,预留资源给系统 cl <- makeCluster(detectCores() - 2) clusterEvalQ(cl, library(dplyr)) # 配置待处理的年份范围,按实际需要调整起止年份即可 year_range <- 1901:2024 data_base_path <- "https://www.ncei.noaa.gov/data/global-hourly/archive/csv/" # 批量处理所有年份压缩包 ISDGlobalHourlyData <- parLapply(cl, year_range, function(cur_year, base_path) { # 生成临时文件路径,退出函数时自动清理临时文件,不占用额外磁盘空间 tmp_tar_file <- tempfile(fileext = ".tar.gz") on.exit({ unlink(tmp_tar_file) unlink(list.files(tempdir(), pattern = "\\.csv$", full.names = TRUE)) }, add = TRUE) # 下载当前年份的压缩包 download.file( url = paste0(base_path, cur_year, ".tar.gz"), destfile = tmp_tar_file, mode = "wb", quiet = TRUE ) # 解压压缩包到临时目录 untar(tmp_tar_file, exdir = tempdir()) csv_path_list <- list.files(tempdir(), pattern = "\\.csv$", full.names = TRUE) # 合并当前年份下所有csv数据 cur_year_data <- bind_rows(lapply(csv_path_list, read.csv)) return(cur_year_data) }) %>% bind_rows() # 关闭并行集群释放资源 stopCluster(cl)
提速注意事项
- 不要把压缩包和解压后的csv长期存在本地工作目录,用系统临时目录+
on.exit()自动清理,既省磁盘空间,也减少手动清理的操作 - 如果不需要全量字段,一定要在
read.csv()中通过colClasses参数指定需要读取的列和对应类型,跳过不需要的列,能减少60%以上的读入时间和内存占用 - Windows系统并行开销高于macOS/Linux,若运行不稳定可以适当调低并行线程数,比如设为总核数的一半
- 如果全量数据大小超过本机内存,不要强行全量读入,可以把每年处理完的数据单独存为
.rds格式文件,后续分析时按需读取对应年份的子集即可
内容的提问来源于stack exchange,提问作者elissafromfallacy
相关产品推荐
相关产品推荐

