Hi,
im implementing a package to create ggplot2 graphs conforming to the companies CI.
I have identified two ways to achieve this goal, but I wonder which one is most futureproof way. Either one has drawbacks.
Firstly, simply use ggplot2::update_geom_defaults()
and set the defaults when loading the package like this:
geoms_color_updates <- c("line", "point")
geoms_fill_updates <- c("point", "bar", "col")
purrr::walk(geoms_color_updates, ~update_geom_defaults(.,
aes(color = utils_colors_company$graph[["green_ci"]]))
)
purrr::walk(geoms_fill_updates, ~update_geom_defaults(.,
aes(fill = utils_colors_company$graph[["green_ci"]]))
)
What rubs me the wrong way is that a global state is used to modify function behaviour which is less then ideal: The standard geoms behave differently depending on the state of the global environment. Not something I like to do.
Secondly, create custom geoms
GeomLineCompany <- ggproto("GeomLineCompany", GeomLine,
default_aes = aes(
color = utils_colors_company$graph[["green_company"]],
linewidth = 1,
linetype = 1,
alpha = NA
)
)
#' geom_line_company
#'
#' @inheritParams ggplot2::geom_line
#' @return
#' @export
geom_line_company <- function(mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
layer(
geom = GeomLineCompany,
data = data,
mapping = mapping,
stat = stat,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
This has the benefit of clearly telegraphing the user that this is the company CI geom and that it behaves differently to the standard one. This would be me preffered solution where it not for the, pardon my french, horrid state of OOP in R. In Python I would simply create a class that inherits from the standard geom and modify the color. Yes, thats what happens with the ggproto class here, but the function that utilises the geom, geom_line_company,
cannot simply be wrapped since I cant inject the different geom via ...
. Though ggproto is sort of OOP the method to use the class isnt tied to it nor does it inherit from it.
I worry that future changes in ggplot2 will cause this approach to break. So whats the best solution?