【问题标题】:Date format for plotting x axis ticks of time series data用于绘制时间序列数据的 x 轴刻度的日期格式
【发布时间】:2012-10-15 13:02:49
【问题描述】:

数据文件的日期是时间序列数据的格式,即 1975M1、1975M2、... 2011M12。使用 R 绘制此数据时,我希望 x 轴在刻度轴上显示月份。

为了正确读取日期,我尝试将 M 替换为 - 以获取 %Y-%m 格式,但这对于 hydroTSM 包中的 drawTimeAxis 似乎并不好,它可能需要 %Y-%M-%d 格式。它会给出错误,即刻度维度的维度数不正确。

另一种解析和格式化数据的方法,如x$newdate <- strptime(as.character(x$date), "%Y-%m") 然后format(x$newdate,""%Y-%m") 也不读取日期并给出错误...所有NA。

date

请给出如何使用日期信息读取此数据的解决方案。

数据文件的一小部分

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

更新:到目前为止的答案通过在 xts 包中使用 %YM%m 或添加获取标准格式的日期来解决正确读取日期的问题。刻度轴的自定义仍然是一个问题。 drawTimeAxis 给出尺寸错误,并且绘图命令不显示超过一年的数据或其他数据的月度标签。自定义刻度轴的任何方法?

【问题讨论】:

  • 在 SO 上找到了以下方法用于刻度线的间距link
  • 该链接中的信息与我的答案中的详细信息确实没有太大区别。

标签: r date plot zoo


【解决方案1】:

也许您没有正确使用 as.yearmon(),因为以下内容对我有用(使用 Gavin 的回答中的 dat):

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

因此,努力让事情正确绘制:

  1. 您的数据:

    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)
    
  2. 使用“zoo”包中的as.yearmon() 转换为xts

    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
    
  3. 绘制数据:

    plot.zoo(dat.xts)
    

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

更新:指定您自己的坐标区

这里有一些可以使用的示例数据(在提出关于 SO 的问题时分享这些示例数据通常很好,因为它可以让其他人更容易复制和解决您的问题)。请注意,对于本示例,我们跳过了使用“xts”包,因为它并不是真正需要的。

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"))

这是使用plot(dat.z, screen = 1, col = 1:2)获得的默认图:

从您的 cmets 看来,您需要像月度标签这样的东西。

  1. 绘制数据,但使用 xaxt = "n" 隐藏 x 轴

    plot(dat.z, screen = 1, col = 1:2, xaxt = "n")
    
  2. 做一些设置工作,为每个月制作一个标签。 (参见?plot.zoo,从那里修改。)

    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
    
  3. 将您的轴添加到您的情节中。可能需要进行一些实验才能找到适合所有物品的尺寸。 las = 2 使标签垂直于轴,如果您真的觉得需要为每年的每个月添加标签,则需要这样做。

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

这是最后的情节:

顺便说一句,如果您收到1977.15 之类的日期,您可能需要阅读一些答案to this question,例如,查看@joran 对pretty() 的使用。

【讨论】:

  • 感谢您的回复。作为 xts 对象的数据集看起来只是最终显示的格式,但图没有月份标签?选择刻度轴的最佳方法是什么?
  • @Anusha,请分享一些数据(可以编造)来证明您遇到的问题,否则我们将无法有效地帮助您。
  • 它与我们这里的数据相同,只是时间序列更长。检查 head(data) 和 class 时,它显示 ts,mts。我尝试了 12 个 obs(也许刻度被隐藏以节省空间),然后将刻度标签显示为 2010.0,.... 2010.8 并且也没有给出 jan feb 标签。我认为添加时间信息可以提供更详细的时间轴。而且不知道为什么 y 轴会膨胀到 38000 到 44000 之类的值。
  • 当我单独绘制每个系列并且观察次数超过 8 时,就会出现这个问题。但即使观察次数更多,我们也必须有办法根据需要间隔刻度轴.
  • 感谢您的详细解答。几个问题:1。为什么y轴值膨胀这么多? 2. 是否可以像任何 x-y 图表一样绘制时间序列,x 轴上的时间和 y 轴上的序列,因为它是真的。为什么刻度不占用数据的值范围? 3. 为什么drawTimeAxis的hydroTSM命令不起作用,出现尺寸错误?
【解决方案2】:

使用您的数据:

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)

您缺少的是您需要在日期中添加一天,以便它们成为as.Date() 的有效输入。可以通过将"-01" 附加到date 的每个元素来完成此位。我们需要添加"-" 分隔符,以明确区分月份和我们添加的新日期。

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

现在我们有了类似的东西

> 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"

我们可以写出as.Date() 可以使用的适当格式:"%YM%m-%d"。请注意,我们在此处包含文字 "M" 和日期部分之前的分隔符 "-"

将其与transform() 一起将结果插入dat 我们有:

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

这给了

> 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

【讨论】:

  • +1 感谢您使用此方法。将数据转换为标准格式以供后续分析似乎更好。
猜你喜欢
  • 1970-01-01
  • 2014-01-10
  • 2014-08-25
  • 2020-09-28
  • 1970-01-01
  • 2013-01-04
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多