R 同一图表上的多个日内时间序列

R 同一图表上的多个日内时间序列,r,ggplot2,time-series,xts,R,Ggplot2,Time Series,Xts,我正在努力解决一些问题,我相信,在R 请考虑以下例子: library(dplyr) library(tidyverse) time = c('2013-01-03 22:04:21.549', '2013-01-03 22:04:22.349', '2013-01-03 22:04:23.559', '2013-01-03 22:04:25.559' ) value1 = c(1,2,3,4) value2 = c(400,500,444,210) data <- data_fram

我正在努力解决一些问题,我相信,在R

请考虑以下例子:

library(dplyr)
library(tidyverse)

time = c('2013-01-03 22:04:21.549', '2013-01-03 22:04:22.349', '2013-01-03 22:04:23.559', '2013-01-03 22:04:25.559' )
value1 = c(1,2,3,4)
value2 = c(400,500,444,210)

data <- data_frame(time, value1, value2)
data <-data %>%  mutate(time = as.POSIXct(time))

> data
# A tibble: 4 × 3
                 time value1 value2
               <dttm>  <dbl>  <dbl>
1 2013-01-03 22:04:21      1    400
2 2013-01-03 22:04:22      2    500
3 2013-01-03 22:04:23      3    444
4 2013-01-03 22:04:25      4    210
在斯塔塔,人们可以简单地说:

twoway (line value1 time, sort ) (line value2 time, sort)

在R,我不知道怎么做。我是不是遗漏了什么?Base R,
ggplot2
,一些奇怪的软件包,任何带有适当定制选项的工作解决方案都可以。一个Base R黑客可以满足您的需要。我会尽力弄清楚哪些组件(蓝色和红色)负责哪些组件。这很难看,但它展示了必要的要点。使用您的数据:

# making sure the left and right sides have the same space
par(mar = c(4,4,1,4) + 0.1)
# first plot
plot(value1 ~ time, data = data, pch = 16, col = "blue", las = 1,
     col.axis = "blue", col.lab = "blue")
grid(lty = 1, col = "blue")
# "reset" the whole plot for an overlay
par(fig = c(0,1,0,1), new = TRUE)
# second plot, sans axes and other annotation
plot(value2 ~ time, data = data, pch = 16, col = "red",
     axes = FALSE, ann = FALSE)
grid(lty = 3, col = "red")
# add the right-axis and label
axis(side = 4, las = 1, col.axis = "red")
mtext("value2", side = 4, line = 3, col = "red")

我添加网格是为了突出一个美学问题:它们没有“整齐地”对齐。如果你同意的话,现在就停下来吧

这里有一种方法(还没有用明显不同的数据范围进行测试)。(根据您的数据和偏好,肯定还有其他方法。)

(尽管红蓝相间的网格线非常糟糕,但它们表明网格实际上对齐得很好。)


注意:
par(fig=c(0,1,0,1),new=TRUE)的使用有点脆弱。在绘图之间进行诸如更改页边距或其他重大更改之类的操作很容易破坏覆盖,除非您进行一些手动操作以查看加法过程的实际结果,否则您不会真正知道。在此“检查”过程中,您可能希望从第二个绘图中删除轴=F,ann=F,以确认至少框和x轴按预期对齐。
ggplot2
的2.2.0版允许定义次轴。现在,第二个时间序列可以适当缩放并显示在同一图表中:

data %>% 
  mutate(value2 = value2 / 100) %>%    # scale value2
  gather(variable, value, -time) %>%   # reshape wide to long
  ggplot(aes(time, value, colour = variable)) + 
  geom_point() + geom_line() + 
  scale_y_continuous(name = "value1", sec.axis = sec_axis(~ . * 100, name = "value2"))

Hadley反复说过(如果你在这个网站上搜索的话),他认为双y轴是误导性的,除非它们只是转换(如Celcius和Fahrenheit)。相反,使用对数刻度或刻面,例如
库(tidyverse);data%%>%gather(var,val,-time)%%>%ggplot(aes(time,val,color=var))+geom_line()+scale_y_log10()
@alistaire这不是重复的,因为这里有x轴的datetime组件,与SO中的许多示例不同。@Noobie,你的说法可以说是主观的(许多人都同意你的观点)最重要的是,这并不代表哈德利的想法。除非你付钱给他,否则别紧张。在这种情况下,我同意多个轴是有意义的。不幸的是,哈德利正在考虑很多其他的不清楚的时候。最重要的是哈德利(写了所有这些的人)对维护他不相信的代码没有兴趣;然而,他热情地鼓励人们编写ggplot扩展来实现这一功能。。。许多人反对双y的论点是,通常有一种更好的方式来展示你想要的东西。例如,为两个数据集编制索引。然而,即使是这样,也可以根据你的数据的时间点索引进行操作。Noobie,如果任何一个答案都足够,你能“接受”它吗?太棒了!!!但是这个图表很可怕,其他一些链接可能很有用:还有。我认为,
ggplot2
做得很好的(许多)事情之一就是遵循“图形语法”,其中大部分是直观的。通过将y轴与点/线(即颜色)的明显区别联系起来,我认为这有助于减轻混淆刻度的担忧。虽然我在这里选择的调色板还有很多需要改进的地方,但应该谨慎行事,以确保鼓励明显的区别。(假设“良好的绘图管理”的概念,对所有数据点使用相同的颜色/点/线类型可能是不负责任的描述。)非常好,但在这里,由于您手动定义了比例,您可能会作弊。有没有可能自动做到这一点?我有很多不同的时间序列…我认为这是非常干净的,但你看到一种方法来自动重新缩放吗?
# one way that may "normalize" the y-axes for you, so that the grid should be identical
y1 <- pretty(data$value1)
y1n <- length(y1)
y2 <- pretty(data$value2)
y2n <- length(y2)
if (y1n < y2n) {
  y1 <- c(y1, y1[y1n] + diff(y1)[1])
} else if (y1n > y2n) {
  y2 <- c(y2, y2[y2n] + diff(y2)[1])
}
# making sure the left and right sides have the same space
par(mar = c(4,4,1,4) + 0.1)
# first plot
plot(value1 ~ time, data = data, pch = 16, col = "blue", las = 1, ylim = range(y1),
     col.axis = "blue", col.lab = "blue")
grid(lty = 1, col = "blue")
# "reset" the whole plot for an overlay
par(fig = c(0,1,0,1), new = TRUE)
# second plot, sans axes and other annotation
plot(value2 ~ time, data = data, pch = 16, col = "red", ylim = range(y2),
     axes = FALSE, ann = FALSE)
grid(lty = 3, col = "red")
# add the right-axis and label
axis(side = 4, las = 1, col.axis = "red")
mtext("value2", side = 4, line = 3, col = "red")
data %>% 
  mutate(value2 = value2 / 100) %>%    # scale value2
  gather(variable, value, -time) %>%   # reshape wide to long
  ggplot(aes(time, value, colour = variable)) + 
  geom_point() + geom_line() + 
  scale_y_continuous(name = "value1", sec.axis = sec_axis(~ . * 100, name = "value2"))