具有2个y轴(次要y轴)的2个ts对象(时间序列)的ggplot

时间:2019-07-16 15:00:22

标签: r ggplot2 time-series yaxis

我想使用2个y轴分别绘制2个ts对象为条形和线条。如何在ggplot中做到这一点?

我有2个ts对象:一个是变量的值,另一个是年度变化。数据是每月一次。我想将两个ts对象绘制到一张图中,值表示为线,增长率表示为条形。为此,我需要一个辅助y轴,因为两个变量的比例非常不同。

我通常使用ts.plot绘制ts对象,该对象很容易容纳次要的y轴,但是我无法绘制条形图,只能绘制线条。

使用ggplot,我在如何使用ts对象方面感到挣扎...使用自动绘图,我可以生成图和辅助轴,但后者似乎确实独立于我的数据。在下面的示例中,如何使线条和线条重叠?

# REPRODUCIBLE EXAMPLE
library(ggplot2)
library(ggfortify)  # to use autoplot
library(seasonal)  # to get the example ts data AirPassengers
library(dplyr)  # to use the pipe-operator

# Genereate year-on-year change
YearOverYear <- function (x,periodsPerYear){
if(NROW(x)<=periodsPerYear){
stop("too few rows")
 }
 else{
 indexes<-1:(NROW(x) - periodsPerYear)
return(c(rep(NA,periodsPerYear), (x[indexes+periodsPerYear]- x[indexes]) / x[indexes]))
  }
}

AirPassengers.gr <- YearOverYear(AirPassengers, 12) %>%
              ts(., start = start(AirPassengers), frequency = 12)

p <- autoplot(AirPassengers, ts.geom = 'line', ts.colour = 'dodgerblue') 
autoplot(AirPassengers.gr*100, ts.geom = 'bar', ts.colour = 'red', p=p) +
  scale_y_continuous(sec.axis = sec_axis(~./1))

1 个答案:

答案 0 :(得分:0)

很高兴认识你,伊莎贝尔

我刚刚将ts.object更改为data.table,然后使用基本的ggplot方法。此外,您可以应用任何技巧。

库负载

library(ggplot2)
library(ggfortify)  # to use autoplot
library(seasonal)  # to get the example ts data AirPassengers
library(dplyr)  # to use the pipe-operator
library(zoo);library(data.table)

数据处理

YearOverYear <- function (x,periodsPerYear){
  if(NROW(x)<=periodsPerYear){
    stop("too few rows")
  }
  else{
    indexes<-1:(NROW(x) - periodsPerYear)
    return(c(rep(NA,periodsPerYear), (x[indexes+periodsPerYear]- x[indexes]) / x[indexes]))
  }
}

AirPassengers.gr <- YearOverYear(AirPassengers, 12) %>%
  ts(., start = start(AirPassengers), frequency = 12)
lubridate::as_date(time(AirPassengers))

DF = data.frame(Passengers = as.matrix(AirPassengers),
                date = zoo::as.Date(time(AirPassengers)))
DF.gr = data.frame(value = as.matrix(AirPassengers.gr),
                date = zoo::as.Date(time(AirPassengers.gr)))
DF = merge(DF,DF.gr, by = 'date')
setDT(DF)

绘图代码

scale_value = max(DF$Passengers, na.rm = TRUE)/ max(DF$value, na.rm = TRUE)

ggplot(DF) + 
  geom_line(aes(x= date, y= Passengers), color = 'dodgerblue') +
  geom_bar(aes(x= date, y = value*scale_value), stat = 'identity') + 
  scale_y_continuous(sec.axis = sec_axis(~./scale_value, name = 'NEW'))

enter image description here

如果您有任何问题,请随时提问。