【问题标题】:read.xlsx reading dates wrong if non-date in column如果列中的非日期,read.xlsx 读取日期错误
【发布时间】:2014-09-29 07:19:10
【问题描述】:

xlsx 包错误地读取日期。我在这里阅读了所有最相似的 Q,并在互联网上进行了侦察,但如果列中存在非日期数据,我无法找到原点发生变化的这种特殊行为。

我有一个小型 Excel 电子表格,您可以从 Dropbox 获取:

https://www.dropbox.com/s/872q9mzb5uzukws/test.xlsx

它有三行两列。第一个是日期,第二个是数字。第三行在日期列中有“总计”。

如果我用read.xlsx 读取前两行并告诉它第一列是日期,那么这有效:

read.xlsx("./test.xlsx",head=FALSE,1,colClasses=c("Date","integer"),endRow=2)
          X1 X2
1 2014-06-29 49
2 2014-06-30 46

这些确实是电子表格中的日期。如果我尝试读取所有三行,就会出现问题:

read.xlsx("./test.xlsx",head=FALSE,1,colClasses=c("Date","integer"))
          X1    X2
1 2084-06-30    49
2 2084-07-01    46
3       <NA> 89251
Warning message:
In as.POSIXlt.Date(x) : NAs introduced by coercion

如果我尝试以整数形式读取,我会得到不同的整数:

> read.xlsx("./test.xlsx",head=FALSE,1,colClasses=c("integer","integer"),endRow=2)
     X1 X2
1 16250 49
2 16251 46
> read.xlsx("./test.xlsx",head=FALSE,1,colClasses=c("integer","integer"))
     X1    X2
1 41819    49
2 41820    46
3    NA 89251

第一个整数使用as.Date(s1$X1,origin="1970-01-01")(Unix 纪元)正确转换,第二个整数使用as.Date(s2$X1, origin="1899-12-30")(Excel 纪元)正确转换。如果我使用 1970 年转换第二批,我会得到 2084 年的日期。

那么:我做错了吗?以整数形式读取是最好的选择,如果有任何 NA,则使用 E​​xcel 纪元进行转换,否则使用 Unix 纪元?还是xlsx 包中的错误?

xlsx 版本是版本:0.5.1

【问题讨论】:

  • 我正要推荐 XLConnect 包,但这似乎有它自己的问题 - 我无法让它读取 first 行:readWorksheet(loadWorkbook("test.xlsx"),"Sheet1",startRow=0) .很奇怪。
  • @StephanKolassa 默认readWorksheet 已设置header = TRUE
  • 这几乎可以肯定是xlxs::read.xlsx 中的一个错误。请注意,如果您指定as.data.frame=FALSEread.xlsx,则在所有4 种情况下(有和没有第三行以及指定"Date""integer"),数值均为4181941820。我会向维护者提出问题。

标签: r excel date r-xlsx


【解决方案1】:

日期可以读取为整数,然后使用openxlsx::convertToDate() 函数转换为日期。

更多here

【讨论】:

    【解决方案2】:

    XLConnect 能够处理这个非常甜蜜的事情:

    test <- readWorksheetFromFile( "~/Downloads/test.xlsx", sheet = "Sheet1", header = FALSE )
    test
                     Col1  Col2
    1 2014-06-29 00:00:00    49
    2 2014-06-30 00:00:00    46
    3         Grand Total 89251
    

    您遇到的问题很明显,第一列是混合类型:characterPOSIXctXLConnect 能够正确读取每个单元格,但会将一列的所有单元格转换为最常见的类型,在本例中为 character

    str(test)
    'data.frame':   3 obs. of  2 variables:
     $ Col1: chr  "2014-06-29 00:00:00" "2014-06-30 00:00:00" "Grand Total"
     $ Col2: num  49 46 89251
    

    【讨论】:

    • 是的,这通常是 R 的一个问题,R 没有适当的多维列表支持。您可以列出列表、矩阵和 data.frames,但都有它们的问题。
    • 添加colTypes=c("Date","integer") 似乎进行了正确的转换并将最后一项设置为NA。我真的不关心最后一项中的文字。
    【解决方案3】:

    您遇到的问题是 Excel 存储自 1900 年 1 月 0 日以来的天数,即 R 从 excel 文件中读取的数字。当您在 R 中转换时,您是根据自 1970 年 1 月 1 日以来的天数进行转换。如果你先减去这两者之间的天数,它应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-10
      • 1970-01-01
      • 2015-03-10
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 2023-02-20
      相关资源
      最近更新 更多