openxlsx2 的 wb_add_comment 为什么不能批量添加批注?
数据小陈
结论
问题出在批注调用处理多个单元格位置时,列选择结果本身没有问题。示例中 which(...) 返回 5 6 7,说明选中了多个列。同一组位置传给 wb_add_fill() 可以正常工作;传给 wb_add_comment() 时,内部的可见性检查收到长度大于 1 的 clientData,于是 if 抛出 the condition has length > 1。
报错发生在 wb_add_comment() 内部处理批注的路径。单列调用成功、多列调用失败,表明当前用法无法安全处理这组多列位置。wb_add_comment() 的帮助文档将 dims 描述为电子表格单元格维度,并以 "A1" 为例;文档没有说明传入 wb_dims() 生成的多位置向量时会如何处理。wb_add_comment 文档
处理方法:逐个单元格添加批注
填充颜色可以一次应用到多个单元格。添加批注时,遍历列索引,每次只传入一个单元格位置:
fill_cells <- function(taxon, character, value, df, wb, color, comment) {
row <- which(df$taxon %in% taxon) + 1L
col <- which(colnames(df) %in% character)
if (!missing(value)) {
wb <- wb$add_data(
x = value,
start_row = row,
start_col = col,
row_names = FALSE
)
}
if (!missing(color)) {
wb <- wb$add_fill(
color = wb_color(name = color),
dims = wb_dims(rows = row, cols = col)
)
}
if (!missing(comment)) {
for (j in col) {
wb <- wb$add_comment(
comment = wb_comment(
text = comment,
width = 4,
author = getOption("openxlsx2.creator")
),
dims = wb_dims(rows = row, cols = j)
)
}
}
wb
}
这样,wb_add_fill() 仍一次接收多个列;循环中的 wb_add_comment() 每次只接收一个列索引。由于 wb_add_comment() 返回更新后的 workbook,每轮都要将结果重新赋给 wb,最后再返回它。
调用时确认行列索引
示例通过 which(df$taxon %in% taxon) + 1 计算 row,额外的 1 用来补偿 Excel 表格中的表头行。col 则是列在 dataframe 中的位置。示例的列选择已排除 NA,因此循环只会对选中的非缺失列添加批注。
如果传入的列名可能重复或不存在,可以在调用前检查索引:
stopifnot(length(row) == 1L, length(col) > 0L)
这个判断适用于 taxon 唯一且确实选中了目标列的情况。如果数据中同一个 taxon 对应多行,应先确定要批注哪些行,再逐个生成单元格位置。
备注:内容仅供参考。
