我试图写一个函数,编辑通过loadWorkbook导入的工作簿,有一个问题,空白单元格被忽略,而不是作为NA处理。下面的代码演示了这个问题。
df <- data.frame(x = c(1, 2, 3, 4, NA, 6), y = c(7, 8, 9, 10, NA, 12))
xlsx::write.xlsx(df, file = 'testdf.xlsx', showNA = FALSE, row.names = FALSE)
testwb <- loadWorkbook(file = 'testdf.xlsx')
sheetnames <- c('Sheet1')
sheets <- lapply(sheetnames, function(name) getSheets(testwb)[[name]])
rows <- getRows(sheets[[1]], rowIndex=1:7)
cells <- getCells(rows, colIndex=1:2)
values <- sapply(unlist(cells), getCellValue)
values
length(values)
当我运行它时,我得到了我所期望的,包括NA:
1.1 1.2 2.1 2.2 3.1 3.2 4.1 4.2 5.1 5.2 6.2 7.1 7.2
“x”“y”“1”“7”“2”“8”“3”“9”“4”“10”NA NA“6”“12”
但是,如果我打开excel文件并手动删除第一行数据,然后再次运行它,我会得到这样的结果:
1.1 1.2 3.1 3.2 4.1 4.2 5.1 5.2 7.1 7.2
“x”“y”“2”“8”“3”“9”“4”“10”“6”“12”
这给我带来了问题,因为当在两个工作表之间进行比较时,如果一个工作表的空白单元格比另一个工作表的空白单元格多,那么它们最终会得到不同数量的值。如何强制它包含NA值?
我尝试手动重建工作簿的副本,以便可以像这样在writeData中使用keepNA参数:
testwb2 <- openxlsx::createWorkbook()
addWorksheet(testwb2, 'Sheet1')
writeData(testwb2, 'Sheet1', read_xlsx('testdf.xlsx', sheet = 1), keepNA = TRUE)
sheetnames <- c('Sheet1')
sheets <- lapply(sheetnames, function(name) getSheets(testwb2)[[name]])
rows <- getRows(sheets[[1]], rowIndex=1:7)
cells <- getCells(rows, colIndex=1:2)
values <- sapply(unlist(cells), getCellValue)
values
length(values)
但是我得到了错误
envRefInferField(x,what,getClass(class(x)),selfEnv)中的错误:“getNumberOfSheets”不是引用类“Workbook”的有效字段或方法名称
我也不明白有没有一个简单的方法来处理这个问题?
1条答案
按热度按时间11dmarpk1#
这个问题有点令人困惑,但这个问题可能已经被回答了几次。我认为现在的情况是这样的:当你删除第一行时,你的电子表格软件会进行某种清理,并从数据中删除空行(它不再是你编写的xlsx文件中xml结构的一部分),
xlsx
包只返回它在工作簿中可以读取的单元格。我已经尝试修复
openxlsx
的类似问题,因此我假设xlsx
的行为类似。下面我创建了一个文件,它的行为与您描述的问题一样,显示
openxlsx
也表现得很淘气,但还有其他表现得很好的包。