所以一直在想这个。基本上,当您创建一个新的原语时,您通常会编写以下组合:
- 层 函数
- 一个stat-ggproto,
- 一个geom-ggproto
只有图层功能需要对用户可见。如果您需要一些新的数据转换方法来制作原始数据,您只需要编写一个stat-ggproto 。如果你有一些新的基于网格的图形要创建,你只需要编写一个geom-ggproto 。
在这种情况下,我们基本上是在堆肥已经存在的层函数,我们真的不需要编写新的 ggprotos。写一个新的layer-function就足够了。此图层功能将创建您已经在使用的三个图层,并按照您想要的方式映射参数。在这种情况下:
- Layer1 – 使用
geom_errorbar
and stat_boxplot
– 来获取我们的误差线
- Layer2 - 使用
geom_boxplot
和stat_boxplot
- 创建箱线图
- 第 3 层 - 用户
geom_label
和stat_summary
- 在框的中心创建具有平均值的文本标签。
当然,您可以编写一个新的stat-ggproto和一个新的geom-ggproto来一次完成所有这些事情。或者,也许您将堆肥并入一个,stat_summary
以及stat_boxplot
三个geom-protos,这用一层来完成。但除非我们遇到效率问题,否则没有什么意义。
无论如何,这是代码:
geom_myboxplot <- function(formula = NULL, data = NULL,
stat = "boxplot", position = "dodge",coef=1.5,
font = "sans", fsize = 18, width=0.6,
fun.data = NULL, fun.y = NULL, fun.ymax = NULL,
fun.ymin = NULL, fun.args = list(),
outlier.colour = NULL, outlier.color = NULL,
outlier.shape = 19, outlier.size = 1.5,outlier.stroke = 0.5,
notch = FALSE, notchwidth = 0.5,varwidth = FALSE,
na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE,...) {
vars <- all.vars(formula)
response <- vars[1]
factor <- vars[2]
mymap <- aes_string(x=factor,y=response)
fun_med <- function(x) {
return(data.frame(y = median(x), label = round(median(x), 3)))
}
position <- position_dodge(width)
l1 <- layer(data = data, mapping = mymap, stat = StatBoxplot,
geom = "errorbar", position = position, show.legend = show.legend,
inherit.aes = inherit.aes, params = list(na.rm = na.rm,
coef = coef, width = width, ...))
l2 <- layer(data = data, mapping = mymap, stat = stat, geom = GeomBoxplot,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(outlier.colour = outlier.colour, outlier.shape = outlier.shape,
outlier.size = outlier.size, outlier.stroke = outlier.stroke,
notch = notch, notchwidth = notchwidth, varwidth = varwidth,
na.rm = na.rm, ...))
l3 <- layer(data = data, mapping = mymap, stat = StatSummary,
geom = "label", position = position, show.legend = show.legend,
inherit.aes = inherit.aes, params = list(fun.data = fun_med,
fun.y = fun.y, fun.ymax = fun.ymax, fun.ymin = fun.ymin,
fun.args = fun.args, na.rm=na.rm,family=font,size=fsize/3,vjust=-0.1,...))
return(list(l1,l2,l3))
}
它允许您现在像这样创建自定义的箱线图:
ggplot(mpg) +
geom_myboxplot( hwy ~ class, font = "sans",fsize = 18)+
theme_grey(base_family = "sans",base_size = 18 )
它们看起来像这样:
注意:我们实际上不必使用该layer
函数,我们可以使用原始stat_boxplot
的geom_boxplot
、、和stat_summary
调用来代替它们。但是,如果我们希望能够从我们的自定义箱线图中控制它们,我们仍然必须填写所有参数,所以我认为这种方式更清晰 - 至少从结构而不是功能的角度来看. 也许不是,这是一个品味问题......
我也没有那种看起来更好看的字体。但我不想跟踪它并安装它。