【问题标题】:data difference in `as.POSIXct` with Excel`as.POSIXct` 与 Excel 的数据差异
【发布时间】:2015-10-17 07:12:44
【问题描述】:

我的实际数据如下:

8/8/2013 15:10
7/26/2013 10:30
7/11/2013 14:20
3/28/2013 16:15
3/18/2013 15:50

当我从 excel 文件中读取此内容时,R 将其读取为:

41494.63
41481.44
41466.60
41361.68
41351.66

所以我使用了as.POSIXct(as.numeric(x[1:5])*86400, origin="1899-12-30",tz="GMT"),我得到了:

2013-08-08 15:07:12 GMT
2013-07-26 10:33:36 GMT
2013-07-11 14:24:00 GMT
2013-03-28 16:19:12 GMT
2013-03-18 15:50:24 GMT

为什么会有时差?如何克服?

【问题讨论】:

  • 不确定这里的答案是什么,但如果这是你的 x,可以试试这个 as.POSIXct(x*60*60*24, tz = "GMT", origin = "1900-01-01")x <- c(41494.63, 41481.44, 41466.60, 41361.68, 41351.66)
  • @DavidArenburg 但分钟不正确。
  • @David 如果我更改日期,我的结果日期也会更改。但在上述情况下,结果日期是正确的。我的问题只有几分钟。
  • 哦,我没有看到你已经尝试过了。无论如何,这是要走的路,它可能是 Excel 在那里搞砸了。您必须对其进行调整以满足您的需求。
  • Kavi 可以分享一下你是如何将数据加载到 R 中的吗?我很想知道像8/8/2013 15:10 这样的原始数据是如何在R 中读取的,比如41494.63。谢谢。

标签: r excel datetime time


【解决方案1】:

问题在于 Excel 的任一 R 都将数字四舍五入到小数点后两位。例如,当您将带有 8/8/2013 15:10 的单元格转换为文本格式(在 Mac OSX 上的 Excel 中)时,您会得到数字 41494.63194

使用时:

as.POSIXct(41494.63194*86400, origin="1899-12-30",tz="GMT")

它会给你:

[1] "2013-08-08 15:09:59 GMT"

这与原始日期相差 1 秒(这也表明 41494.63194 已四舍五入到小数点后五位)。

可能最好的解决方案是将您的 excel 文件导出到 .csv 或制表符分隔的 .txt 文件,然后将其读入 R。这至少给了我正确的日期:

> df
            datum
1  8/8/2013 15:10
2 7/26/2013 10:30
3 7/11/2013 14:20
4 3/28/2013 16:15
5 3/18/2013 15:50

【讨论】:

  • 41494.63194 最后 4 次重复给出了正确的时间。四舍五入在这里肯定是有罪的。
【解决方案2】:

这就是它在 Windows 系统上的工作方式。这是源 Excel 2010 文件的样子:

date                num         secs        constant    Rtime
(mm/dd/yyyy)        (in Excel)  (num*86400) (Windows)   (secs-constant) 
08/08/2013 15:10    41494.63    3585136200  2209161600  1375974600
07/26/2013 10:30    41481.44    3583996200  2209161600  1374834600
11/07/2013 14:20    41585.60    3592995600  2209161600  1383834000
03/28/2013 16:15    41361.68    3573648900  2209161600  1364487300
03/18/2013 15:50    41351.66    3572783400  2209161600  1363621800

Rtime <- c(1375974600,1374834600,1383834000,1364487300,1363621800)
as.POSIXct(Rtime,origin="1970-01-01",tz="GMT")
#[1] "2013-08-08 15:10:00 GMT" "2013-07-26 10:30:00 GMT"
#[3] "2013-11-07 14:20:00 GMT" "2013-03-28 16:15:00 GMT"
#[5] "2013-03-18 15:50:00 GMT"

为什么是这个常数?首先,因为 Excel 和 Office 在处理日期时通常是一团糟。说真的,看这里:Why is 1899-12-30 the zero date in Access / SQL Server instead of 12/31?

2209161600 是 1970-01-01 和 1899-12-30 的 POSIXct 之间的秒差,这是 Windows 上 Excel 中的 0 点。

dput(as.POSIXct(2209161600,origin="1899-12-30",tz="GMT"))
#structure(0, tzone = "GMT", class = c("POSIXct", "POSIXt"))

【讨论】:

    【解决方案3】:

    给定

    x <- c("8/8/2013 15:10","7/26/2013 10:30","7/11/2013 14:20","3/28/2013 16:15","3/18/2013 15:50")
    

    (读取为字符向量),

    试试

    x <- as.POSIXct(x, format = "%m/%d/%Y %H:%M", tz = "GMT")
    

    对我来说,它正确读取为 POSIXct 向量。

    【讨论】:

    • 由于 OP 指定了 tz 参数,我认为最好不要忘记它,因为在我们居住的意大利 x 将有 CEST 作为时区。
    • 就我而言,x
    • @kavi - 你应该在你的问题中指定你正在使用 Excel - 这会有所不同,因为 Excel 在处理日期方面很疯狂。
    • 好的!抱歉让问题看起来不同。我做了更改。
    • 我不明白这个答案是如何回答这个问题的。
    【解决方案4】:

    也许这与 R 如何读取数据有关。这里只是一个lubridate 的例子似乎效果很好。

    x <- "8/8/2013 15:10"
    library(lubridate)
    dmy_hm(x, tz = "GMT")
    [1] "2013-08-08 15:10:00 GMT"
    

    【讨论】:

    • 我猜这也不能回答问题。
    • @DavidArenburg 我认为你是对的,但 OP 的最后一个问题是“如何克服它?”然后我提供了一种使用lubridate 来解决问题的方法。一种务实的方法,它不能解释问题发生的原因,但允许 OP 打败它。我相信 R 的高级用户会解决这个问题并获得大量支持。
    • 但是 OP 输入的是一个数字,例如 41494.63,而不是 "8/8/2013 15:10"
    • @DavidArenburg...嗯...我认为你是对的。在这一点上,也许 OP 必须共享他/她用来读取数据的代码,以便更好地了解正在发生的事情。我会问的。
    猜你喜欢
    • 1970-01-01
    • 2011-01-05
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    相关资源
    最近更新 更多