自动化手动Excel读取和清理多个电子表格的标题和子标题在R;我更喜欢使用dplyr/readxl来处理杂乱的数据

lhcgjxsq  于 2023-05-04  发布在  其他
关注(0)|答案(1)|浏览(84)

我每年都有多个Excel文件需要读取。每个文件都有多个与我的分析相关的电子表格,我只想保留这些电子表格。问题是,前3行是标题和子标题,我需要折叠成一个单一的列名。我一直无法找到一个解决方案,到目前为止,因为工作表可能是不同的列长度,我需要捕捉所有的数据。我也想将一个文件中的所有工作表/dfs合并到一个数据框架中。
我的目标是:

  • 读入电子表格
  • 只保留相关的表单
  • 从每张图纸读入数据
  • 取前三行(标题)并折叠成一个列名,应用于每个相关工作表以创建列表中的数据

这就是我想要的数据的最终输出。我附上了一个样本电子表格。
| 副标题1_id|副标题1_name|副标题1_...|团队A1_subheading1_a1|等等等等|
| --------------|--------------|--------------|--------------|--------------|
| 1|蓝色|等等|五百|废话|
| 二|橙子|等等|七百|废话|
| 三|紫色|等等|九百|废话|
sample file
示例代码-第一次尝试,只要每个电子表格的列具有相同的长度,就可以很好地工作

library(tidyverse)
library(readxl)
path <- "C:/Example Spreadsheet.xlsx"
#read the sheets and only keep the cost share sheets
sheets <- excel_sheets(path)[grep("Data of interest",excel_sheets(path) )] # simplified to a single    line
#read the data, as a list
excel_data <- lapply(sheets, read_excel, path = path, skip=0)

#convert to DF
temp_df <- excel_data %>%
 bind_rows()

第二次尝试-这得到了适当的输出,但是,我最终不得不为每个单独的df重复相同的代码

#Loop below converts each list element to a df
for (i in 1:length(excel_data)) {
assign(paste0("group_", i), as.data.frame(excel_data[[i]]))
}

#extract each row element 
names1 <- str_remove(names(group_1), "All fields .+|[.]+[:digit:]+") %>% na_if("")
names2 <- str_remove(group_1[1,], "[.]+[:digit:]+") %>% na_if("")
names3 <- str_remove(group_1[2,], "[.]+[:digit:]+") %>% na_if("") 
#combine each row element
temp_names <- tibble(n1 = c(names1, rep(NA, length(names3) - length(names1))), 
                     n2 = c(names2, rep(NA, length(names3) - length(names2))), 
                     n3 = names3) %>%
  fill(n1, n2) %>%
  replace_na(list(n1 = "")) %>%
  mutate(full_name = paste(n1,n2,n3, sep = "_"))

#add the full name
temp_names <- temp_names$full_name
#convert to df and combine elements
names(group_1) <- temp_names[1:ncol(group_1)]

group_1 <- group_1[-c(1,2),]
mnemlml8

mnemlml81#

除非我从您的问题中遗漏了什么,否则这段代码应该可以为任何列或表集获得所需的结果。

library(tidyverse)
library(readxl)
path <- "C:/Example Spreadsheet.xlsx"
sheets <- excel_sheets(path)[grep("Data of interest",excel_sheets(path) )]

colname_data <- sapply(lapply(sheets, read_excel, path = path, skip =0, col_names = F), function(x) x[1:3,])
excel_data <- lapply(sheets, read_excel, path = path, skip=3, col_names = F)

for (i in 1:length(excel_data)) {
  colname_data[[i]] <- colname_data[[i]] %>% 
                       t() %>% 
                       as_tibble() %>% 
                       fill(V1, V2, V3)
  colname_data[[i]] <- colname_data[[i]] %>% 
                       replace(is.na(colname_data[[i]]), '') %>% 
                       mutate(col_name = paste(V1, V2, V3, sep='_'))
  col_names <- gsub('^_', '', colname_data[[i]]$col_name)
  
  colnames(excel_data[[i]]) <- col_names
}

bind_rows(excel_data)

然后,您可以按照自己的意愿对列进行排序。

相关问题