I tend to end up with incredibly complicated ggplot
figures with a lot of customization, so I naturally add these to my code as functions so that I can easily reuse them. The problem occurs when I want to use one of my custom functions, but tweaking it slightly, e.g. removing or adding an aesthetic to a geom that I already define inside the function. My options for this are:
Create an almost duplicate function but with the particular change added, and the function name changed to reflect this or
Add arguments to the function that change how the
ggplot
is constructed inside the function
I try and opt for 2. as much as I can because it clearly reduces the amount of redundancy and clutter in my scripts.
However there are times when 2. almost degenerates to 1. inside the function by forcing me to retype whole geom functions containing several arguments. I will give a very simple example, baring in mind that the functions I have are far complicating and worth the pondering that I am doing here:
gg_custom_point <- function(df, xvar, yvar, gvar=NA){
g <- ggplot(df)
if(is.na(gvar)){
# do geom without colour
g <- g + geom_point(aes_string(x=xvar, y=yvar))
}
else{
# do geom with colour - mostly redundant code
g <- g + geom_point(aes_string(x=xvar, y=yvar, colour=gvar))
}
return(g)
}
# I can use the same function to make slightly different custom plots
gg_custom_point(mtcars, "wt", "mpg")
gg_custom_point(mtcars, "wt", "mpg", "qsec")
The issue is that I have had to retype the whole geom_point
instead of being able to just add the aesthetic. The redundancy problem is even worse if I ever want to be able to tweak multiple aesthetics for one geom - I have to type out the geom containing every combination of aesthetics possible form the given arguments.
I could do this:
g <- g + geom_point(aes_string(x=xvar, y=yvar))
if(!is.na(gvar)){
# Add to the global aesthetic - no need to retype the whole geom
g <- g + aes_string(colour=gvar)
}
But this does not scale to multiple geoms using multiple data sources, since all geoms would need to use this colour aesthetic and the gvar
column.
Is there a way of easily adding aesthetics to specific geoms that have already been added to the ggplot
object? Alternatively, is there a better way of using ggplot2
functions and geoms inside a custom function?