将 xlsx 电子表格读入 R 时如何包含空列?

How do I include empty columns when reading an xlsx spreadsheet into R?

我正在尝试编写一个 R 脚本,它将遍历大约 100 个小的 Excel 电子表格并堆叠 15-20 行具有完整单元格的行(每个小文件的确切行数各不相同)合二为一。

我正在使用的这段代码(包含在循环中)读取文件,但跳过不包含任何条目的列。

newDf <- read.xlsx(filename,sheetName="Coding",header=FALSE,
    rowIndex=rows,colIndex=columns)

我目前的解决方法是创建一个虚拟的第一个数据框,每列都有值;然后,当我将每个 newDf 绑定到它时,这些列将被迫对齐。但我希望有更好的方法。

如有任何帮助,我们将不胜感激。谢谢。

如果您愿意使用 XLConnect 包而不是 xlsx,函数 XLConnect::readWorksheet 允许您指定 startColendCol , 和 autofitCol 个参数,这将为您解决这个问题:

library(XLConnect)
##
# wb1 <- loadWorkbook("~/tmp/tmp1.xlsx", create = FALSE)
# wb2 <- loadWorkbook("~/tmp/tmp2.xlsx", create = FALSE)
df1 <- readWorksheet(
  object = wb1,
  sheet = "sheet1",
  startCol = 1,
  endCol = 3,
  autofitCol = FALSE)
##
df2 <- readWorksheet(
  object = wb2,
  sheet = "sheet1",
  startCol = 1,
  endCol = 3,
  autofitCol = FALSE)
##
R> head(df1,3)
  A B Col3
1 1 6   NA
2 2 7   NA
3 3 8   NA
R> head(df2,3)
  A B  C
1 1 6 11
2 2 7 12
3 3 8 13

其中 df1 是从仅包含两个非空列的工作表中读取的(请参阅下面的数据)。


数据:

wb1 <- loadWorkbook("~/tmp/tmp1.xlsx", create = TRUE)
createSheet(wb1, "sheet1")
writeWorksheet(
  object = wb1,
  data = data.frame(
    A = 1:5,
    B = 6:10),
  sheet = "sheet1")
saveWorkbook(wb1)
##
wb2 <- loadWorkbook("~/tmp/tmp2.xlsx", create = TRUE)
createSheet(wb2, "sheet1")
writeWorksheet(
  object = wb2,
  data = data.frame(
    A = 1:5,
    B = 6:10,
    C = 11:15),
  sheet = "sheet1")
saveWorkbook(wb2)

我不确定为什么 read.xlsx 有这种行为...

有几个可能的解决方案。第一种是使用 XLSX 包中的 readColumns 函数,而不是 read.xlsx:

wb     <- loadWorkbook("c:/path/to/your/xlsx/file")
sheets <- getSheets(wb)
sheet <- sheets[["NAMEOFSHEET"]]
newDf <- readColumns(sheet, startColumn=1, endColumn=3, startRow=1, endRow=4)

或者,您可以按原样继续阅读文件,使用 read.xlsx,然后只需在后面添加空白列:

if("COLUMN_THAT_SHOULD_BE_THERE" %in% colnames(newDf) == FALSE){
    newDf$COLUMN_THAT_SHOULD_BE_THERE <- NA
}

也许尝试使用 read.xlsx2

我用这种格式保存了一个 Excel 文件并将其命名为 test.xlsx:

    id blank   names
 1:  1          John
 2:  2         Jacob
 3:  3        Jingel
 4:  4        Heimer
 5:  5       Schmidt
 6:  6           Joe
 7:  7        Public
 8:  8          Jane
 9:  9           Doe
10: 10        Ramsey

还有一个我只是删除了列 header,我将其命名为 test2.xlsx:

    id    names
 1:  1     John
 2:  2    Jacob
 3:  3   Jingel
 4:  4   Heimer
 5:  5  Schmidt
 6:  6      Joe
 7:  7   Public
 8:  8     Jane
 9:  9      Doe
10: 10   Ramsey

当我用 read.xlsx 读入它们时,blank 被跳过 只有 没有命名时:

> read.xlsx("test.xlsx",sheetIndex=1)
   id blank   names
1   1    NA    John
2   2    NA   Jacob
3   3    NA  Jingel
4   4    NA  Heimer
5   5    NA Schmidt
6   6    NA     Joe
7   7    NA  Public
8   8    NA    Jane
9   9    NA     Doe
10 10    NA  Ramsey

> read.xlsx("test2.xlsx",sheetIndex=1)
   id   names
1   1    John
2   2   Jacob
3   3  Jingel
4   4  Heimer
5   5 Schmidt
6   6     Joe
7   7  Public
8   8    Jane
9   9     Doe
10 10  Ramsey

但是,如果我在 test2.xlsx 上使用 read.xlsx2

> read.xlsx2("test.xlsx",sheetIndex=1)
   id X.   names
1   1       John
2   2      Jacob
3   3     Jingel
4   4     Heimer
5   5    Schmidt
6   6        Joe
7   7     Public
8   8       Jane
9   9        Doe
10 10     Ramsey

现在它被读取为名为 X.factor 列。

如果我尝试将其扩展为有一堆空列,这就是我得到的结果:

> read.xlsx2("test3.xlsx",sheetIndex=1)
   id X.   names X..1  names2 X..2  names3 X..3  names4
1   1       John         John         John         John
2   2      Jacob        Jacob        Jacob        Jacob
3   3     Jingel       Jingel       Jingel       Jingel
4   4     Heimer       Heimer       Heimer       Heimer
5   5    Schmidt      Schmidt      Schmidt      Schmidt
6   6        Joe          Joe          Joe          Joe
7   7     Public       Public       Public       Public
8   8       Jane         Jane         Jane         Jane
9   9        Doe          Doe          Doe          Doe
10 10     Ramsey       Ramsey       Ramsey       Ramsey

所以 read.xlsx2 创建的名字也是可以预见的。另外(我无法确定我在哪里听到这个,所以我无法找到它),我认为通常使用 read.xlsx2 是一个很好的做法——更快,等等

我也可以从 ?read.xlsx 添加这个:

The read.xlsx2 function does more work in Java so it achieves better performance (an order of magnitude faster on sheets with 100,000 cells or more). The result of read.xlsx2 will in general be different from read.xlsx, because internally read.xlsx2 uses readColumns which is tailored for tabular data.

所以@user1578653 使用底层 readColumns 的建议仅使用 read.xlsx.