Date format for plotting x-axis titles of time series data

Data files have a date - format, i.e. 1975M1, 1975M2, ... 2011M12 for time series data. when plotting this data with R, I want the x axis to display months on the tick axis.

To read the dates correctly, I tried replacing M with - to get the% Y-% m format, but that doesn't seem good for drawTimeAxis from the hydroTSM package, which may require the% Y-% M-% d format. It gives an error that the wrong number of measurements to measure ticks.

Another method for analyzing and formatting data is as in x$newdate <- strptime(as.character(x$date), "%Y-%m") , and then format(x$newdate,""%Y-%m") also does not read the date and gives an error ... all NA.

date <- as.Date (data [, 1] an error that the character string is not in the standard unambiguous format and ts <- read.zoo (xts, as.yearmon (x [, 1])) gives bad margins in the data lines .

Please give a decision on how this data can be read with date information.

A small subset of the data file

 date x x2 1975M1 112.44 113.12 1975M2 113.1 114.36 1975M3 115.04 114.81 1975M4 117.65 115.35 1975M5 119.5 116.92 1975M6 121.4 118.56 1975M7 120.64 118.97 1975M8 119.12 119.84 1975M9 118.91 120.59 1975M10 120.58 122.3 1975M11 121.26 123.35 1975M12 122.34 123.33 

Update. The answers still solve the problem of reading the date correctly using% YM% m in the xts package or adding a day to get the standard format. Setting the tick axis is still a problem. DrawTimeAxis gives a measurement error, and the graph commands do not show monthly labels for more than one year of data or otherwise. Any methods for setting the axis of the marks?

+6
source share
2 answers

Perhaps you are not using as.yearmon() correctly, because the following works for me (using dat from Gavin's answer):

 library(zoo) dat$date <- as.yearmon(dat$date, "%YM%m") 

Thus, while working on drawing things correctly:

  • Your data:

     dat <- read.table(text = "date x x2 1975M1 112.44 113.12 1975M2 113.1 114.36 1975M3 115.04 114.81 1975M4 117.65 115.35 1975M5 119.5 116.92 1975M6 121.4 118.56 1975M7 120.64 118.97 1975M8 119.12 119.84 1975M9 118.91 120.59 1975M10 120.58 122.3 1975M11 121.26 123.35 1975M12 122.34 123.33", header = TRUE) 
  • Convert to xts using as.yearmon() from the "zoo" package.

     library(xts) # Will also load zoo dat.xts <- xts(dat[-1], order.by = as.yearmon(dat$date, "%YM%m")) dat.xts # x x2 # Jan 1975 112.44 113.12 # Feb 1975 113.10 114.36 # Mar 1975 115.04 114.81 # Apr 1975 117.65 115.35 # May 1975 119.50 116.92 # Jun 1975 121.40 118.56 # Jul 1975 120.64 118.97 # Aug 1975 119.12 119.84 # Sep 1975 118.91 120.59 # Oct 1975 120.58 122.30 # Nov 1975 121.26 123.35 # Dec 1975 122.34 123.33 
  • Building your data:

     plot.zoo(dat.xts) 

    enter image description here

     plot.zoo(dat.xts, plot.type="single", col = c("red", "blue")) 

    enter image description here

Update: specifying your own axes

Here are some examples of data that you can work with (it’s usually nice to share such exemplary data when asking questions about SO, as this makes it easier for others to replicate and fixes problems). Please note that in this example we skipped the use of the xts package, as it is not really needed.

 set.seed(1) dat <- data.frame(date = paste0(rep(1975:1977, each = 12), "M", rep(1:12, times = 3)), x1 = runif(36, min = 100, max = 140), x2 = runif(36, min = 100, max = 140)) library(zoo) # xts is actually unnecessary if this is all you're doing # Convert your data to a `zoo` object dat.z <- zoo(dat[-1], order.by = as.yearmon(dat$date, "%YM%m")) 

This is the default graph obtained using plot(dat.z, screen = 1, col = 1:2) :

enter image description here

From your comments, it seems like you want something like monthly tags.

  • Build data, but suppress the x axis with xaxt = "n"

     plot(dat.z, screen = 1, col = 1:2, xaxt = "n") 
  • Make some adjustments to have a label for each month. (See ?plot.zoo where it ?plot.zoo from.)

     tt <- time(dat.z) # The following is just the sequence 1:36. # If you wanted only every third month plotted, # use a sequence like ix <- seq(1, length(tt), 3) ix <- seq_along(tt) # What format do you want for your labels. # This yields abbreviated month - abbreviated year fmt <- "%b-%y" labs <- format(tt, fmt) # Generate the vector of your labels 
  • Add your axis to your plot. It may take several experiments to find the right sizes for everything. las = 2 makes the labels perpendicular to the axis, which is required if you really feel the need to include a label for each month of each year.

     axis(side = 1, at = tt[ix], labels = labs[ix], tcl = -0.7, cex.axis = 0.7, las = 2) 

Here is the final plot:

enter image description here

By the way, if you get dates like 1977.15 , etc., you can read some answers to this question , for example, looking at using @joran pretty() .

+17
source

Use of your data:

 dat <- read.table(text = "date x x2 1975M1 112.44 113.12 1975M2 113.1 114.36 1975M3 115.04 114.81 1975M4 117.65 115.35 1975M5 119.5 116.92 1975M6 121.4 118.56 1975M7 120.64 118.97 1975M8 119.12 119.84 1975M9 118.91 120.59 1975M10 120.58 122.3 1975M11 121.26 123.35 1975M12 122.34 123.33", header = TRUE) 

What you are missing is that you need to add a day to your dates so that they are valid entries for as.Date() . This bit can be done by adding "-01" to each date element. We need to add the separator "-" to clearly distinguish the month from the new day that we are adding.

 paste0(as.character(date), "-01") ## temporary step, not needed 

Now we have something that resembles

 > with(dat, paste0(date, "-01")) ## temporary step, not needed [1] "1975M1-01" "1975M2-01" "1975M3-01" "1975M4-01" "1975M5-01" [6] "1975M6-01" "1975M7-01" "1975M8-01" "1975M9-01" "1975M10-01" [11] "1975M11-01" "1975M12-01" 

We can write the appropriate format that as.Date() can use: "%YM%m-%d" . Please note that we include the literal "M" and the delimiter before the "-" part of the day.

Introducing this with transform() to insert the result back into dat , we have:

 ## full solution dat <- transform(dat, date = as.Date(paste0(date, "-01"), format = "%YM%m-%d")) 

What gives

 > dat date x x2 1 1975-01-01 112.44 113.12 2 1975-02-01 113.10 114.36 3 1975-03-01 115.04 114.81 4 1975-04-01 117.65 115.35 5 1975-05-01 119.50 116.92 6 1975-06-01 121.40 118.56 7 1975-07-01 120.64 118.97 8 1975-08-01 119.12 119.84 9 1975-09-01 118.91 120.59 10 1975-10-01 120.58 122.30 11 1975-11-01 121.26 123.35 12 1975-12-01 122.34 123.33 
+2
source

All Articles