--- title: "Building a Factory" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Building a Factory} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(factory) ``` To build a function factory, begin by writing the function that you want to generalize (like a normal function). Here we'll generalize a function to add a color scale to a ggplot using a custom palette. ```{r function to generalize} my_scale_color <- function(discrete = TRUE, reverse = FALSE, ...) { my_palette <- c( "#772277", "#333388", "#1144aa", "#55aa11", "#f40000", "#f47a00", "#ffe314" ) if (reverse) { my_palette <- rev(my_palette) } pal <- colorRampPalette(my_palette, ...) if (discrete) { ggplot2::discrete_scale( aesthetics = "colour", scale_name = "my_color_scale", palette = pal, ... ) } else { ggplot2::scale_color_gradientn(colors = pal(256),) } } ggplot2::ggplot(mtcars) + ggplot2::aes(x = mpg, y = cyl, color = factor(gear)) + ggplot2::geom_point() + my_scale_color() ``` We could conceivably want to generalize this function to create a similar function, given a palette and (optionally) the name of the scale. ```{r genericized function} my_scale_color_generic <- function(discrete = TRUE, reverse = FALSE, ...) { my_palette <- this_palette if (reverse) { my_palette <- rev(my_palette) } pal <- colorRampPalette(my_palette, ...) if (discrete) { ggplot2::discrete_scale( aesthetics = "colour", scale_name = this_scale_name, palette = pal, ... ) } else { ggplot2::scale_color_gradientn(colors = pal(256),) } } ``` We can use `factory::build_factory` to turn that function into a factory. ```{r sample factory} my_scale_color_factory <- build_factory( fun = my_scale_color_generic, this_palette, this_scale_name = "my_color_scale" ) ``` Using our factory with the values we started with should reproduce the original function. ```{r using the factor} my_scale_color_factory( this_palette = c( "#772277", "#333388", "#1144aa", "#55aa11", "#f40000", "#f47a00", "#ffe314" ) ) ``` Note: If you use `factory` to build a factory in a package, we recommend that you copy/paste the resulting function definition into your package, rather than using the `factory::build_factory` call directly in your package. This will allow you to better comment your code, and will avoid [build errors](https://r6.r-lib.org/articles/Portable.html#potential-pitfalls-with-cross-package-inheritance).