xlsx R:遍历文件列表以检查所有 sheet 个名称;创建一个空白 sheet 如果它不存在

xlsx R: looping through list of files to check all sheet names; create a blank sheet if it does not exist

我正在尝试编写一个遍历 Excel 工作簿文件的循环,检查所有 sheet 的名称以确保每个 excel 工作簿具有三个 sheet 中的名称('sheet1'、'sheet2'、'sheet3' - 以任何顺序排列)。如果缺少其中一个 sheet 名称,我想在缺少 sheet.

的工作簿中创建缺少的 sheet(空白)
  1. 我目前一直在确保工作簿的 sheet 名称匹配(在列表 'result' 中)- 我尝试了下面的脚本,但 'correct_sheet' returns 为空
  2. 添加sheets,addWorksheet(openxlsx)可以循环使用吗? map (purr) 会比 for 循环更好吗/map 可以应用于列表中的工作簿吗?

我从来没有像这样处理过多个文件,我愿意接受任何和所有的建议/方法!

library(tidyverse)
library(readxl)
'%notin%' <- Negate('%in%')


all_files <- list.files(path="./path/to/files'", pattern = "*.xlsx", full.names = T)

#write files to a list to see the sheet names
result <- lapply(all_files, function(x) {
  all_sheets <- excel_sheets(x)  
}

#filter by which workbooks match criteria
correct_sheet <- lapply(result, FUN = function(x) {
  correct_sheet <- intersect(result, c('sheet1', 'sheet2', 'sheet3') )
})

#Add worksheet in a loop
for (result %notin% correct_sheet){

  
}


我是老同学。我喜欢 for 循环。当你来自其他语言时就会发生这种情况!

所以我将跳过所有 lapply 无法解释正在发生和正在做的事情

new_data = "" # a placeholder for the data you will insert in an new empty sheet

for (file %in% all_files) {
# open the file and get it's sheets
sheets = excel_sheets(file)

# check if the file has the sheet you want
if ( "sheet1" %in% sheets) {
 # do nothing
} else {
# if not - create a sheet
xlsx::write.xlsx(new_data,
 file, # You may need to add the path? 
 sheetName="sheet1",
 append=TRUE)
} #if you are checking for all 3 sheets and adding any 3 missing, add another for loop?


R 纯粹主义者会说这是缓慢且低效的。我的问题是它需要多快?它需要多可读?

你可以试试这个-

library(readxl)
all_files <- list.files(path="./path/to/files'", pattern = "*.xlsx", full.names = T)
#Get sheet names
sheet_names <- lapply(all_files, excel_sheets)
#If less than 3 sheets
inds <- lengths(sheet_names) < 3

Map(function(x, y) {
  addsheets <- setdiff(c('sheet1', 'sheet2', 'sheet3'), y)
  for(sh in addsheets) {
    xlsx::write.xlsx(data.frame(a = 1), x, sheetName=sh,append=TRUE)
  }
}, all_files[inds], sheet_names[inds])

出于某种原因,传递一个空数据框给我一个错误,所以我创建了一个包含一行和一列的虚拟数据集以添加到新的 sheet.