1

我正在尝试创建保存多个格式化的 Excel 文件,每个文件都是从某个数据框中按一个因子子集的。

这是我迄今为止尝试过的一个例子

# Create data
df <- data.frame(category = rep(c("a","b","c","d"),times = 20),
                 values = rnorm(20,5,2))

# Create workbooks named after specific level of factor
l1 <- sapply(levels(df$category), assign, value = createWorkbook())

# Create styles
hs <- createStyle(fgFill = "#808080", border = "bottom", textDecoration = "bold")
lt8 <- createStyle(bgFill = "#ff0000")
gt30 <- createStyle(bgFill = "#00b0f0")
grn <- createStyle(bgFill = "#00b000")

# For loop
for (i in l1) {
  addWorksheet(i, names(i))
  writeData(i, names(i), df[df$category == names(i),], headerStyle = hs)

  conditionalFormatting(i, names(i), cols = 1:2, rows = 2:nrow(df[df$category == names(i),]), rule = "$B2<2", type = "expression", style = lt8)
  conditionalFormatting(i, names(i), cols = 1:2, rows = 2:nrow(df[df$category == names(i),]), rule = "$B2>=7", type = "expression", style = gt30)
  conditionalFormatting(i, names(i), cols = 1:2, rows = 2:nrow(df[df$category == names(i),]), rule = "AND($B2>=4, $B2<5.5)", style = grn)
  setColWidths(i, names(i), cols=1:2, widths = "auto")

  saveWorkbook(paste(i, ".wb", sep = ""), file = paste(i, " Report ", ".xlsx", sep = ""))
}

每次,我都会遇到这个错误 Error in if (tolower(sheetName) %in% tolower(wb$sheet_names)) stop("A worksheet by that name already exists! Sheet names must be unique case-insensitive.")

这是我第一次尝试分配任何工作表,所以我不确定为什么我不断收到此错误。

最终,我想通过重复过程保存子集和格式化的 Excel 工作簿,因为我的真实数据会产生更多的工作簿。工作簿必须是分开的,将这些子集放在工作表中是行不通的。

任何关于如何实现这一目标的建议将不胜感激。


4

1 回答 1

1

您的错误来自这一行:

addWorksheet(i, names(i))

因为names(i)是空的:

> names(l1[['a']])
character(0)

您最好循环遍历 的名称l1,这样您就有了所需的类别,并使用它从列表中提取适当的工作簿。就像是:

for (i in names(l1)) {
  wb = l1[[i]]
  addWorksheet(wb, i)
  category_data <- df[df$category == i,]
  writeData(wb, i, category_data, headerStyle = hs)

  conditionalFormatting(wb, i, cols = 1:2, rows = 2:nrow(category_data), rule = "$B2<2", type = "expression", style = lt8)
  conditionalFormatting(wb, i, cols = 1:2, rows = 2:nrow(category_data), rule = "$B2>=7", type = "expression", style = gt30)
  conditionalFormatting(wb, i, cols = 1:2, rows = 2:nrow(category_data), rule = "AND($B2>=4, $B2<5.5)", style = grn)
  setColWidths(wb, i, cols=1:2, widths = "auto")

  saveWorkbook(wb, file = paste(i, " Report ", ".xlsx", sep = ""))
}

这里还有一个微妙的错误:

l1 <- sapply(levels(df$category), assign, value = createWorkbook())

createWorkbook()只被调用一次,所以你有同一个工作簿的 4 个副本。这意味着最终保存将包含所有 4 个选项卡。相比:

> identical(l1$a, l1$b)
[1] TRUE

有 2 次单独调用createWorkbook()

> identical(createWorkbook(), createWorkbook())
[1] FALSE

可能值得只循环不同的类别,并在循环内创建工作簿。那是:

library(openxlsx)

# Create data
df <- data.frame(category = rep(c("a","b","c","d"),times = 20),
                 values = rnorm(20,5,2))

# Create styles
hs <- createStyle(fgFill = "#808080", border = "bottom", textDecoration = "bold")
lt8 <- createStyle(bgFill = "#ff0000")
gt30 <- createStyle(bgFill = "#00b0f0")
grn <- createStyle(bgFill = "#00b000")

# For loop
for (i in levels(df$category)) {
  wb <- createWorkbook()
  addWorksheet(wb, i)
  category_data <- df[df$category == i,]
  writeData(wb, i, category_data, headerStyle = hs)

  conditionalFormatting(wb, i, cols = 1:2, rows = 2:nrow(category_data), rule = "$B2<2", type = "expression", style = lt8)
  conditionalFormatting(wb, i, cols = 1:2, rows = 2:nrow(category_data), rule = "$B2>=7", type = "expression", style = gt30)
  conditionalFormatting(wb, i, cols = 1:2, rows = 2:nrow(category_data), rule = "AND($B2>=4, $B2<5.5)", style = grn)
  setColWidths(wb, i, cols=1:2, widths = "auto")

  saveWorkbook(wb, file = paste(i, " Report ", ".xlsx", sep = ""))
}
于 2019-12-06T02:49:23.157 回答