dygraph中的日期(使用R和xts)显示比数据

时间:2017-07-08 21:52:54

标签: r rstudio xts dygraphs

这是我的第一个stackoverflow问题,所以请提前为礼节或演示中的任何失误道歉。

我正在使用R中的dygraphs()包(运行Mavericks的Mac上的3.3.3,使用RStudio)来绘制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" (在月份缩写之后,我无法找到摆脱不需要的逗号的方法。)

sample dygraph showing incorrect date in legend

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

我尝试了各种各样的解决方案,但到目前为止还没有任何效果。这看起来像一个bug,但是我不清楚bug在哪里(在dtgraphs包中?在RStudio中?在xts中?)。我的问题似乎与此类似:

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

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

****编辑于7/10/17回应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 viewer 中检查时,图例中的日期过早,但在浏览器中查看时导出的html中的日期是正确的。

所以看起来这个问题可能就在其他地方。

在我的原始示例中使用lubridate as_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"))

2 个答案:

答案 0 :(得分: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有很好的支持。花点时间学习它,一次一个问题。

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

代码

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)

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

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

希望这有帮助。

图表

enter image description here

数据

enter image description here

答案 1 :(得分:0)

上周我再次开始开发这个应用程序时,我刚刚回到了这个问题,我终于能够解决它了。在我最初编写的代码中,问题必须特别与 valueFormatter 函数的 dyAxis() 属性中的 JavaScript 函数有关,我使用该函数为 dygraph时间序列(此代码未在我的原始问题中显示)。在我 2017 年的代码中,我有:

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

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

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

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 年没有理解他的回答!