如何编写可以引用输入图的 ggplot '+'-pipeable 函数
How to write a ggplot '+'-pipeable function that can refer to the input plot
我正在尝试编写一个可以使用基于“+”的 ggplot2 语法调用的函数。
myplot + myfunction
具体来说,我正在编写的函数使 y 轴关于零对称,因此它需要确定输入图的 y 轴范围。
所以让,
ylim_sym <- function(p){
get_y_range <- function(p){
ggplot2::ggplot_build(p)$layout$panel_ranges[[1]]$y.range
}
max_offset <- max(abs(get_y_range(p)))
p + ylim(- max_offset, max_offset)
}
有了这个功能,下面的工作:
qplot(x = 1:10, y = exp(rnorm(10))) %>% ylim_sym()
但这行不通,因为 +.gg
和 %>%
之间存在一些优先级问题:
qplot(x = 1:10, y = exp(rnorm(10))) +
geom_abline(slope = 0) %>%
ylim_sym()
(我可以写后者 (all_my_ggplot_pipeline) %>% ylim_sym()
但它的语法非常难看)。
理想情况下,我希望能够编写 ylim_sym
这样它就可以像这样通过管道传输,
qplot(x = 1:10, y = exp(rnorm(10))) + ylim_sym()
但我无法弄清楚如何在 ylim_sym
中访问 +
的 LHS 上的情节
有什么想法吗?
我通过执行以下操作解决了这个问题。
StatSymYLim <- ggproto(
"StatSymYLim", Stat,
compute_group = function(data, scales) {
out <- data.frame(
x = median(data$x),
y = c(-1, 1) * max(abs(data$y))
)
out
},
required_aes = c("x", "y")
)
ylim_sym <- function(...){
geom_blank(..., stat = StatSymYLim)
}
然后按要求进行以下工作:
qplot(x = 1:10, y = exp(rnorm(10))) +
geom_abline(slope = 0) +
ylim_sym()
我对 ggplot2 内部结构的理解相当不稳定,所以这可能是一个天真的解决方案。
注意:您的函数需要更新,因为对象的结构略有变化
使用 package ggfun 这会起作用:
# devtools::install_github("moodymudskipper/ggfun")
library(ggfun)
ylim_sym <- function(p){
get_y_range <- function(p){
ggplot2::ggplot_build(p)$layout$panel_params[[1]]$y.range
}
max_offset <- max(abs(get_y_range(p)))
p + ylim(- max_offset, max_offset)
}
qplot(x = 1:10, y = exp(rnorm(10))) +
geom_abline(slope = 0) +
ylim_sym
我正在尝试编写一个可以使用基于“+”的 ggplot2 语法调用的函数。
myplot + myfunction
具体来说,我正在编写的函数使 y 轴关于零对称,因此它需要确定输入图的 y 轴范围。
所以让,
ylim_sym <- function(p){
get_y_range <- function(p){
ggplot2::ggplot_build(p)$layout$panel_ranges[[1]]$y.range
}
max_offset <- max(abs(get_y_range(p)))
p + ylim(- max_offset, max_offset)
}
有了这个功能,下面的工作:
qplot(x = 1:10, y = exp(rnorm(10))) %>% ylim_sym()
但这行不通,因为 +.gg
和 %>%
之间存在一些优先级问题:
qplot(x = 1:10, y = exp(rnorm(10))) +
geom_abline(slope = 0) %>%
ylim_sym()
(我可以写后者 (all_my_ggplot_pipeline) %>% ylim_sym()
但它的语法非常难看)。
理想情况下,我希望能够编写 ylim_sym
这样它就可以像这样通过管道传输,
qplot(x = 1:10, y = exp(rnorm(10))) + ylim_sym()
但我无法弄清楚如何在 ylim_sym
+
的 LHS 上的情节
有什么想法吗?
我通过执行以下操作解决了这个问题。
StatSymYLim <- ggproto(
"StatSymYLim", Stat,
compute_group = function(data, scales) {
out <- data.frame(
x = median(data$x),
y = c(-1, 1) * max(abs(data$y))
)
out
},
required_aes = c("x", "y")
)
ylim_sym <- function(...){
geom_blank(..., stat = StatSymYLim)
}
然后按要求进行以下工作:
qplot(x = 1:10, y = exp(rnorm(10))) +
geom_abline(slope = 0) +
ylim_sym()
我对 ggplot2 内部结构的理解相当不稳定,所以这可能是一个天真的解决方案。
注意:您的函数需要更新,因为对象的结构略有变化
使用 package ggfun 这会起作用:
# devtools::install_github("moodymudskipper/ggfun")
library(ggfun)
ylim_sym <- function(p){
get_y_range <- function(p){
ggplot2::ggplot_build(p)$layout$panel_params[[1]]$y.range
}
max_offset <- max(abs(get_y_range(p)))
p + ylim(- max_offset, max_offset)
}
qplot(x = 1:10, y = exp(rnorm(10))) +
geom_abline(slope = 0) +
ylim_sym