【问题标题】:Date in dygraph (using R and xts) shows one day earlier than datadygraph 中的日期(使用 R 和 xts)显示比数据早一天
【发布时间】:2017-07-08 21:52:53
【问题描述】:

这是我的第一个 stackoverflow 问题,因此对于礼仪或演示中的任何失误,请提前道歉。

我正在使用 R 中的 dygraphs() 包(在运行 Mavericks 的 Mac 上使用 RStudio 的 3.3.3)来绘制 18 世纪剧院的票房收入时间序列。日期从 1789-04-14 到 1791-03-07。我正在使用最新版本的 xts 包(0.10-0),但问题与之前的版本相同。作为 xts 对象,数据如下所示:

head(receipts.xts)
              kr
1789-04-14 15454
1789-04-20  6985
1789-04-22  4545
1789-04-24  5342
1789-04-26  5791
1789-04-28 25139

为索引导入的日期类型为date。 (“kr”代表“kreuzer”,是当时货币记账单位的细分。)

创建dygraph的代码是:

dygraph(receipts.xts, 
        main = "Opera Receipts, Burgtheater, 1789-1791") %>%
  dySeries("kr", label = "Receipts (kr)") %>% 
  dyLegend(show="always", hideOnMouseOut =FALSE) %>% dyRangeSelector()

图例中的所有日期都比 xts 对象中的相应日期早一天。这显示在随附的屏幕截图中,其中第一个数据点是 1789-04-14,但在图例中的 RStudio 查看器中显示为“Apr, 13, 1789”(我一直无法找到摆脱月份缩写后不需要的逗号。)

奇怪的是,当我将此图表保存为 html 时,网页上的图例显示正确的日期!

我尝试了多种可能的解决方案,但到目前为止都没有奏效。这看起来像一个错误,但我不清楚错误在哪里(在 dygraphs 包中?在 RStudio 中?在 xts 中?)。我的问题似乎与此类似:

Date bug in dygraph in dygraphs package (using JavaScript) in R

但这个问题似乎从来没有明确的答案。我可以获得正确日期以显示在 RStudio 查看器的图例中的唯一方法是在用作 xts 对象索引的所有日期(使用 lubridate)中添加一天,但是日期在html.

**** 于 2017 年 7 月 10 日编辑以回应 Dirk 的回复 ****

我已经意识到日期的“隐藏”时区问题的可能性,并尝试了许多其他方法来解决这个问题,尽管尚未按照 Dirk 的建议使用 Sys.setenv() 设置时区。我刚刚试过,它也不能解决问题。这次我的步骤是:

operas$Date <- as.character(operas$Date)
Sys.setenv(tz="UTC")
receipts.xts <- xts(operas$Receipts, as.Date(operas$Date))
colnames(receipts.xts) <- "kr"

(在原始数据框中,日期已经是 date 类型,但我想从头开始展示这个问题。)dygraphs 代码与我原来的示例相同。

结果相同:在 RStudio 查看器中查看时,图例中的日期提前了一天,但在浏览器中查看时,导出的 html 中的日期是正确的。

所以看起来问题可能出在其他地方。

在我的原始示例中使用lubridateas_date() 仅反映了我最近尝试修复的一种情况。我的原始代码使用了 as.Date()。不过谢谢指点。

**** 一些示例数据 ****

> dput(receipts.test)
structure(list(Date = c("1789-04-14", "1789-04-20", "1789-04-22", 
"1789-04-24", "1789-04-26", "1789-04-28", "1789-04-30", "1789-05-02", 
"1789-05-04", "1789-05-06"), Receipts = c(15454L, 6985L, 4545L, 
5342L, 5791L, 25139L, 6897L, 4268L, 2400L, 4515L)), .Names = c("Date", 
"Receipts"), row.names = c(NA, 10L), class = c("tbl_df", "tbl", 
"data.frame"))

【问题讨论】:

标签: r xts dygraphs


【解决方案1】:

所以让我们做一个小教程。从日期开始,转换为 POSIXct,然后格式化:

R> format(as.POSIXct(as.Date("2017-07-08")))
[1] "2017-07-07 19:00:00"
R> 

看看会发生什么?我在芝加哥,从午夜减去的五个小时是我与 UTC 的偏移量。一种可能的解决方法是将时区设置为 UTC:

R> Sys.setenv(TZ="UTC")
R> format(as.POSIXct(as.Date("2017-07-08")))
[1] "2017-07-08"
R> 

现在相同的输入数据被正确地“打印”为相同的日期。

教训:警惕DatePOSIXct 的转换。您需要的只是正确的时区(用于格式化的上下文)。

最后,您真的不需要 lubridate 包来调整日期。 R 本身就可以做到这一点:

R> as.Date("2017-07-08")
[1] "2017-07-08"
R> as.Date("2017-07-08") + 1:3
[1] "2017-07-09" "2017-07-10" "2017-07-11"
R> 

日期和时间对于程序员和用户来说都是一个挑战。 R 有 great 支持。花点时间学习它,一次一个问题。

编辑:好的,在我再次被拖进去之后,这里有代码和图表。

代码

d <- structure(list(Date = c("1789-04-14", "1789-04-20", "1789-04-22", 
                             "1789-04-24", "1789-04-26", "1789-04-28", 
                             "1789-04-30", "1789-05-02", 
                             "1789-05-04", "1789-05-06"), 
                   Receipts = c(15454L, 6985L, 4545L, 5342L, 5791L, 25139L, 
                                6897L, 4268L, 2400L, 4515L)), 
            .Names = c("Date", "Receipts"), 
            row.names = c(NA, 10L), 
            class = c("tbl_df", "tbl", "data.frame"))

library(xts)
x <- xts(d[,2, drop=FALSE], order.by=as.Date(d[,1]))

library(dygraphs)
dygraph(x)

这是发布的结构,使用Date 作为索引类型快速转换为xts

我们完成了。如图所示,第一次观察结果显示为 4 月 14 日。

希望这会有所帮助。

图表

数据

【讨论】:

  • 欢迎来到 StackOverflow。很高兴听到这有帮助 - 您现在可以“投票”(点击向上箭头)和/或“接受”(点击勾选标记,只有提出问题的人才能看到)。
  • 非常感谢您的评论!我在原来的问题中添加了一些内容作为重播。底线:使用 Sys.setenv() 设置时区并不能解决问题。
  • 请提供数据样本,例如how to provide a minimally reproducible example.
  • 我之前没有使用过 dput()。我已经在本地完成了,但是如何将它放在 stackoverflow 上?我只是复制并粘贴 dput() 输出的内容吗? (很抱歉提出新问题。)
  • 这是常用的用法。
【解决方案2】:

当我上周再次开始开发这个应用程序时,我最近才回到这个问题,我终于能够解决它。在我最初编写的代码中,问题与 dyAxis() 函数的 valueFormatter 属性中的 JavaScript 函数有关,该函数用于为 dygraph 时间序列构建图例(此代码是我原来的问题中没有显示)。在我 2017 年的代码中,我有:

dyAxis("x", valueFormatter = "function(ms) {
                                 return new Date(ms).toDateString()}",
        rangePad=5
)

其中ms 是“自UTC 时间1970 年1 月1 日午夜以来经过的毫秒数”(如here 所述)。此数字源自xts 对象的行索引(日期)。据我了解,Chrome(和 Opera)会根据本地时区自动解释函数 toDateString()(无论 xts 索引和从它派生的毫秒数是否明确为 UTC),而 Firefox 和 Safari 则根据到 UTC。 (我了解了 Chrome 和 Firefox here 之间的不同行为。)

我的解决方案是在 valueFormatter 的函数中显式构建 dygraph 图例的日期(这也允许我控制输出的日期格式):

dyAxis("x", valueFormatter = "function(ms) {
         dow = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
         months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
         temp = new Date(ms);
         day = dow[temp.getUTCDay()];
         date = temp.getUTCDate().toString();
         month = months[temp.getUTCMonth()];
         year = temp.getUTCFullYear().toString();
         legend = day + ', ' + date + ' ' + month + ' ' + year;
         return legend
   }",
          rangePad=5
          )

使用getUTCDay()getUTCMonth() 确保从ms 派生的日期和月份数字是UTC,无论浏览器如何。

据我测试,此解决方案适用于 Chrome、Opera、Firefox、Safari 和 RStudio 浏览器。我希望其他人会发现这很有用。我向 Dirk Eddelbuettel 道歉,因为在 2017 年没有理解他的回答!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-17
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 2014-08-03
    相关资源
    最近更新 更多