我需要编写一个函数,使用ggplot2
可以快速地绘制双轴图。我知道双轴图通常已经被弃用了,但如果你想观察时间序列中的相似模式,它仍然可能会有用(对于所有不同意的人,请严格技术对待这个问题)。实际上,使用ggplot2
的sec_axis()
函数是可行的,但需要定义公式。因此,这是我尝试自动计算的结果:
dual_plot <- function(data, x, y_left, y_right){
x <- ensym(x)
y_left <- ensym(y_left)
y_right <- ensym(y_right)
ratio_model <- lm(eval(y_left) ~ eval(y_right), data = data)
data %>%
select(!!x, !!y_left, !!y_right) %>%
mutate(!!y_right := predict(ratio_model)) %>%
gather(k, v, -!!x) %>%
ggplot() +
geom_line(aes(!!x, v, colour = k)) +
scale_y_continuous(sec.axis = sec_axis(~ . / ratio_model$coefficients[[2]] -
ratio_model$coefficients[[1]],
name = rlang::as_string(y_right))) +
labs(y = rlang::as_string(y_left))
}
然而,
lm
可能适合一个反向趋势系数,使趋势相反,这真的很误导。因此,我需要另一种方法来计算这个公式 - 要么使用带有系数限制的线性回归,要么使用巧妙的方法来拟合公式。如何在 R 中实现?或者替代 sec_axis
的选择,可以自动绘制双轴图?@编辑:一个例子是:
df <- structure(list(date = structure(c(17167, 17168, 17169, 17170,
17171, 17172, 17173, 17174, 17175, 17176, 17177, 17178, 17179,
17180, 17181), class = "Date"), y_right = c(-107073.90734625,
-633197.630546488, -474626.43291613, -306006.801458608, 56062.072352192,
522580.236751187, 942796.389093215, -101845.73678439, -632658.677118481,
-479257.088784885, -303439.231633988, 50273.2477880417, 521669.062954895,
948127.92455586, -107073.90734625), y_left = c(1648808.16, 3152543.07,
2702739.91, 2382616.25, 1606089.88, 1592465.75, 1537283.99, 2507221.61,
3049076.19, 3125424.4, 2774215.1, 2356412.98, 1856506.41, 1477195.08,
2485713.2)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-15L))
df %>%
dual_plot(date, y_left, y_right)
计算出的比率模型具有方向系数-1.02
,因此y_right
被反转(在函数下降时,绘制的函数上升,反之亦然),从而会产生误导。
y_left
是稳定的,但是y_right
在不同的 facets 中会发生变化。我们可以使用mutate_at(vars(!!!y_right), ~scales::rescale(.x, to = left_range))
来缩放y_right
变量,但是在sec_axis
内进行相反的缩放并不那么清晰。 - jakesscales = "free_y"
时,次要轴没有更新的bug存在(将进行研究,然后提交)。然后有像你描述的控制问题,你可能只想释放次要轴。在这种方法中,我会为每个组创建一个图,并使用ggarrange
或类似的工具将它们放在单个图中。肯定不是理想的解决方案。我会在我的答案中更新这个注意事项。 - ravic_