问题
This is my first stackoverflow question, so apologies in advance for any lapses in etiquette or presentation.
I am using the dygraphs() package in R (3.3.3 on a Mac running Mavericks, using RStudio) to graph a time series of box-office receipts from an 18th-century theater. The dates run from 1789-04-14 to 1791-03-07. I'm using the newest version of the xts package (0.10-0), but the problem was identical in the previous version. As an xts object the data looks like this:
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
The dates imported for the index are of type date
.
('kr' stands for 'kreuzer,' a subdivision of the monetary unit of account at the time.)
The code to create the dygraph is:
dygraph(receipts.xts,
main = "Opera Receipts, Burgtheater, 1789-1791") %>%
dySeries("kr", label = "Receipts (kr)") %>%
dyLegend(show="always", hideOnMouseOut =FALSE) %>% dyRangeSelector()
All dates in the legend show one day earlier than the corresponding date in the xts object. This is shown in the attached screenshot, where the first datapoint is 1789-04-14, but shows in the RStudio viewer in the legend as "Apr, 13, 1789" (I have not been able to find a way to get rid of the unwanted comma after the month abbreviation.)
Oddly, when I save this graph as html, the legend on the webpage shows the correct date!
I've tried a very wide variety of possible solutions, but nothing so far has worked. This looks like a bug, but it's not clear to me where the bug is (in the dygraphs package? in RStudio? in xts?). My question seems similar to this one:
Date bug in dygraph in dygraphs package (using JavaScript) in R
But that question seems never to have had a definitive answer. The only way I can get the proper dates to display in the legends in the RStudio viewer is to add one day to all the dates (using lubridate) that are used as the index of the xts object, but then the dates are incorrect in the html.
**** Edit on 7/10/17 in response to Dirk's reply ****
I'd already been aware of the potential of the "hidden" timezone problem with the dates, and had tried a number of other approaches to fix that, although not yet setting the timezone with Sys.setenv()
as Dirk suggested. I just tried that, and it doesn't fix the problem either. My steps this time were:
operas$Date <- as.character(operas$Date)
Sys.setenv(tz="UTC")
receipts.xts <- xts(operas$Receipts, as.Date(operas$Date))
colnames(receipts.xts) <- "kr"
(In the originating dataframe the dates are already of date
type, but I wanted to start from scratch in showing this problem.) The dygraphs
code is then the same as in my original example.
The results are identical: dates in the legend are one day too early when examined in the RStudio viewer, but are correct in the exported html when viewed in a browser.
So it looks like the problem is probably somewhere else.
The use of lubridate
's as_date()
in my original example only reflected one of my more recent attempts at a fix. My original code had used as.Date(). But thanks for the pointer.
**** Some sample data ****
> 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"))
回答1:
So let's do a little tutorial. Start with a date, convert to a POSIXct and then format:
R> format(as.POSIXct(as.Date("2017-07-08")))
[1] "2017-07-07 19:00:00"
R>
See what happens? I am in Chicago, and the five hours subtracted from midnight are my offset to UTC. One possible fix is to set the timezone to UTC:
R> Sys.setenv(TZ="UTC")
R> format(as.POSIXct(as.Date("2017-07-08")))
[1] "2017-07-08"
R>
Now the same input data is correctly "printed" as the same date.
Lesson: Be wary of Date
to POSIXct
conversions. All you needed here is the proper timezone (for the context of the formatting).
Lastly, you really do not need the lubridate package to adjust a date. R itself does that just fine:
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>
Dates and times are challenging for programmers and users. R has great support. Take your time and learn it, one issue at a time.
Edit: Ok, after I got dragged into this again, here are code and a chart.
Code
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)
This is the structure as posted, quickly converted to an xts
using Date
as the index type.
And we're done. As the chart shows, the first observation is shown as April 14 just as it should.
Hope this helps.
Chart
Data
来源:https://stackoverflow.com/questions/44991072/date-in-dygraph-using-r-and-xts-shows-one-day-earlier-than-data