编写user defined function实现多csv文件数据wrangling流程自动化
需求目标
编写自定义函数,实现多个.csv文件的数据清洗流程自动化。
现有数据说明
共有3个待处理.csv文件,分别为Finland_caucasian.csv、Mexico_hispanic.csv和Jamaica_black.csv。
以Finland_caucasian.csv为例,其数据框结构如下:
date <- rep('1999',9) cityID <- c(1001,1001,1001,1002,1002,1002,1005,1005,1005) country <- rep('FIN',9) name <- rep('caucasian',9) prov_code <- c(1,1,1,2,2,3,3,2,3) class <- c(1,2,5,1,2,5,1,2,5) gender <- c('M','M','F','F','F','M','F','M','M') savings_month1 <-c(100.12,105.11,109.11,94.13,34.00,201.91,154.39,212.76,233.48) savings_month2 <-c(110.15,115.12,193.21,194.13,334.50,21.13,164.19,292.67,235.85) savings_month3 <-c(109.15,159.12,199.22,199.18,339.59,291.95,169.94,299.78,233.22) data<- data.frame(date,cityID,name,country,prov_code,class,gender,savings_month1,savings_month2,savings_month3) data
原始未封装清洗流程
# 自定义函数模板:读取文件夹内所有csv文件 ############################################################################# data_wrangler <- function(input_multi_csvfiles){ # 导入每个csv文件 for(files in filenames){ # 清洗逻辑 } } # 测试代码 data_wrangler(files in folder path) ################################################################################################ # 清洗流程代码 library(dplyr) #步骤1:读取全部三个文件到R中 data = read.csv("filepath//file_name.csv") # 'Finland_caucasian.csv','Mexico_hispanic.csv' and 'Jamaica_black.csv' #步骤2:选择需要的列 df <- data%>%select(date:gender,savings_month1:savings_month3) # 使用冒号选择列区间,避免其他csv文件中间夹杂无用列 #步骤3:打印prov_code, country,name, class的唯一值校验 print(unique(df$prov_code)) print(unique(df$country)) print(unique(df$name)) print(unique(df$class)) #步骤4:根据class过滤数据 # 要求自动适配每个文件的唯一country(FIN、MEX、JAM)和name(caucasian、hispanic、black),不需要手动填写 country_name_df <-subset(df,country == 'FIN' & name == 'caucasian' & class >= 1 & class <= 5) # 其他csv的class范围是0到8,只保留1到5的记录 #步骤5:给列名添加对应class前缀 df10 <- filter(country_name_df,class == 1) colnames(df10) <- paste('1',colnames(df10),sep = '_') df11 <- filter(country_name_df,class == 2) colnames(df11) <- paste('2',colnames(df11),sep = '_') df12 <- filter(country_name_df,class == 5) colnames(df12) <- paste('5',colnames(df12),sep = '_') #步骤6:按列合并三个过滤后的数据框 df15 <- cbind(df10,df11,df12) # 校验df15中class列的内容 unique(df15$`5_prov_code`) #步骤7:最终数据清洗 df20<- df15%>%select(`1_date`:`1_gender`) df30 <-select(df15,contains("month")) # 选择所有包含month的列,如'1_savings_month1', '3_savings_month2'等 target <- df15$`1_prov_code` final_df <- cbind(df20,df30,target) #步骤8:导出每个处理完成的csv文件 # 命名格式为wrangled_Finland+caucasian.csv, wrangled_Mexico+hispanic.csv,wrangled_Jamaica+black.csv write.csv(final_df,'wrangled_FIN+caucasian.csv',row.names = FALSE)
需求更新说明
- 运行历史版本代码出现报错
- 列名排序要求:
gender_1后的列需按如下顺序排列:savings_month1_1、savings_month1_2、savings_month1_5、savings_month2_1、savings_month2_2、savings_month2_5、savings_month3_1、savings_month3_2、savings_month3_5 - 修改
savings_month1:savings_month3选择逻辑后出现新报错
实现方案
以下为修正所有问题、适配全部需求的最终代码,使用tidyverse生态实现,逻辑更简洁不易报错:
library(tidyverse) data_wrangler <- function(folder_path) { # 获取文件夹下所有csv文件路径 file_paths <- list.files(folder_path, pattern = "\\.csv$", full.names = TRUE) # 批量处理每个文件 walk(file_paths, function(path) { # 读取文件 df <- read.csv(path, stringsAsFactors = FALSE) # 步骤1:选择所需列,规避列位置问题 df <- df %>% select(date, cityID, name, country, prov_code, class, gender, savings_month1, savings_month2, savings_month3) # 步骤2:打印唯一值校验 cat("===== 当前处理文件:", basename(path), " =====\n") cat("prov_code唯一值:", unique(df$prov_code), "\n") cat("country唯一值:", unique(df$country), "\n") cat("name唯一值:", unique(df$name), "\n") cat("class唯一值:", unique(df$class), "\n\n") # 步骤3:过滤class 1-5,自动适配当前文件的country和name curr_country <- unique(df$country)[1] curr_name <- unique(df$name)[1] df_filtered <- df %>% filter(country == curr_country, name == curr_name, class %in% c(1,2,5)) # 步骤4:长宽表转换替代手动拆分合并,自动处理列名 df_wide <- df_filtered %>% pivot_wider(names_from = class, values_from = c(date, cityID, name, country, prov_code, gender, savings_month1, savings_month2, savings_month3), names_glue = "{.value}_{.class}") # 步骤5:按要求排序列 final_df <- df_wide %>% select(date_1, cityID_1, name_1, country_1, prov_code_1, gender_1, savings_month1_1, savings_month1_2, savings_month1_5, savings_month2_1, savings_month2_2, savings_month2_5, savings_month3_1, savings_month3_2, savings_month3_5, target = prov_code_1) # 步骤6:导出文件 out_name <- paste0("wrangled_", curr_country, "+", curr_name, ".csv") write.csv(final_df, file.path(folder_path, out_name), row.names = FALSE) }) } # 测试调用,将括号内替换为你的csv所在文件夹路径即可 # data_wrangler("C:/your/csv/folder/path")
代码说明
- 自动识别文件夹下所有csv文件,不需要手动输入文件名
- 自动适配每个文件的country和name值,无需手动修改过滤条件
- 使用长宽表转换替代手动拆分合并,避免列拼接错位问题
- 严格按照要求的列顺序排序,直接满足输出格式
- 所有路径自动处理,避免手动拼接路径报错
内容的提问来源于stack exchange,提问作者nasa313
相关产品推荐
相关产品推荐

