r - 如何在R中一次清理多个excel文件?
问题描述
我有一百多个excel文件需要清理,所有文件都在同一个数据结构中。下面列出的代码是我用来清理单个 excel 文件的代码。文件的名称都在结构中,例如“abcdefg.xlsx”
library('readxl')
df <- read_excel('abc.xlsx', sheet = 'EQuote')
# get the project name
project_name <- df[1,2]
project_name <- gsub(".*:","",project_name)
project_name <- gsub(".* ","",project_name)
# select then needed columns
df <- df[,c(3,4,5,8,16,17,18,19)]
# remane column
colnames(df)[colnames(df) == 'X__2'] <- 'Product_Models'
colnames(df)[colnames(df) == 'X__3'] <- 'Qty'
colnames(df)[colnames(df) == 'X__4'] <- 'List_Price'
colnames(df)[colnames(df) == 'X__7'] <- 'Net_Price'
colnames(df)[colnames(df) == 'X__15'] <- 'Product_Code'
colnames(df)[colnames(df) == 'X__16'] <- 'Product_Series'
colnames(df)[colnames(df) == 'X__17'] <- 'Product_Group'
colnames(df)[colnames(df) == 'X__18'] <- 'Cat'
# add new column named 'Project_Name', and set value to it
df$project_name <- project_name
# extract rows between two specific characters
begin <- which(df$Product_Models == 'SKU')
end <- which(df$Product_Models == 'Sub Total:')
## set the loop
in_between <- function(df, start, end){
return(df[start:end,])
}
dividers = which(df$Product_Models %in% 'SKU' == TRUE)
df <- lapply(1:(length(dividers)-1), function(x) in_between(df, start =
dividers[x], end = dividers[x+1]))
df <-do.call(rbind, df)
# remove the rows
df <- df[!(df$Product_Models %in% c("SKU","Sub Total:")), ]
# remove rows with NA
df <- df[complete.cases(df),]
# remove part of string after '.'
NeededString <- df$Product_Models
NeededString <- gsub("\\..*", "", NeededString)
df$Product_Models <- NeededString
然后我可以得到一个结构良好的数据框。结构良好的数据框示例
你们能帮我写一个代码,它可以帮助我一次清理所有的excel文件。所以,我不需要运行这个代码一百次。然后,将所有文件聚合成一个大的 csv 文件。
解决方案
您可以使用lapply
(base R) 或map
( purrr
package) 通过一组命令读取和处理所有文件。lapply
并map
遍历一个向量或列表(在本例中为文件名的列表或向量),将相同的代码应用于向量或列表的每个元素。
例如,在下面的代码中,它使用map
(map_df
实际上,它返回单个数据帧,而不是单独数据帧的列表),file_names
是文件名的向量(或文件路径 + 名称,如果文件不在工作目录)。...all processing steps...
是您问题中的所有代码都可以处理df
成您想要的形式:
library(tidyverse) # Loads several tidyverse packages, including purrr and dplyr
library(readxl)
single_data_frame = map_df(file_names, function(file) {
df = read_excel(file, sheet="EQUOTE")
... all processing steps ...
df
}
现在您有了一个从所有 Excel 文件生成的大型数据框。您现在可以将其另存为csv
文件,例如write_csv(single_data_frame, "One_large_data_frame.csv")
.
您可能还可以做其他事情来简化代码。例如,要重命名 的列df
,您可以使用recode
函数 (from dplyr
)。我们通过首先将内置mtcars
数据框的名称更改为与数据中的名称相似来演示这一点。然后我们用recode
改几个名字:
# Rename mtcars data frame
set.seed(2)
names(mtcars) = paste0("X__", sample(1:11))
# Look at data frame
head(mtcars)
# Recode three of the column names
names(mtcars) = recode(names(mtcars),
X__1="New.1",
X__5="New.5",
X__9="New.9")
或者,如果名称的顺序始终相同,您可以这样做(使用您的数据结构):
names(df) = c('Product_Models','Qty','List_Price','Net_Price','Product_Code','Product_Series','Product_Group','Cat')
或者,如果您的 Excel 文件有列名,您可以使用skip
参数read_excel
跳到标题行,然后再读入数据。这样,您将直接从 Excel 文件中获得正确的列名。由于看起来您还需要从前几行中获取项目名称,因此您可以先读取这些行,然后单独调用read_excel
并使用range
参数,和/或n_max
参数仅获取相关行或单元格项目名。
推荐阅读
- python - Python groupby 根据一列聚合多列
- google-tag-manager - 用于服务器端标记的 GTM 中的 Facebook 像素等效项是什么?
- cadence-workflow - 使用命令行运行工作流时,如何使工作流运行无限长时间?
- python - 更改函数列表时出现意外结果 (lambda)
- java - 在我使用 Firebase 的 Android 项目中,我收到此警告:W / System: Ignoring header X-Firebase-Locale because its value is null
- flutter - 如何正确模拟 Flutter Fire Firebase 函数?
- php - 如何使用日光浴室按日期过滤
- javascript - jQuery:删除动态添加的项目后重新索引顺序
- flutter - 应用程序空闲较长时间后通知丢失 - 一个信号 sdk 在颤动
- inno-setup - Inno 设置:在 .net dll 中添加第三方引用不起作用