I have a custom function that calls ggplot. I'd like to make one of the ggplot arguments optional - for example, changing the color of geom_point. I know two ways to do this, as shown below; one is to specify a default if the optional argument is not provided, and the other is to wrap the whole ggplot function (here, geom_point()
) in an if statement. Neither of these is ideal in my case - the argument I'm using has no easy default, and the ggplot function itself is already in an if/else if/else statement in my code, meaning that I'd end up with a lot of nested if statements. Is there any way to pass an argument saying essentially, "ignore this argument, use your default behavior"?
Here's a very basic example of the two ways that do work:
library(ggplot2)
library(dplyr)
# Opt 1 - specify a default; not viable in my actual problem due to lack of default
fun_default <- function(df, x, y, color="red"){
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
geom_point(color=color)
p
}
# Opt 2 - use an if statement for the whole argument
# workable but cumbersome in my actual problem, since I'd have to repeat the if/else multiple times throughout the code
fun_if <- function(df, x, y, color=NULL){
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
{if(is.null(color)) { geom_point() }
else { geom_point(color = color)}}
p
}
fun_default(mtcars, wt, mpg, color="blue")
fun_if(mtcars, wt, mpg, color="blue")
fun_if(mtcars, wt, mpg)
What I'd like to do is either nest an if statement inside the geom_point call, or set a color argument that would default to whatever ggplot's default is, without specifying the default on my own. In my head this would look something like one of the following (obviously neither of these actually work):
# if statement inside of geom_point()
fun_wish1 <- function(df, x, y, color=NULL){
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
geom_point( {if(!is.null(color)) {color=color}} )
p
}
# somehow tell geom_point to ignore color or use its default for color
fun_wish2 <- function(df, x, y, color=NULL){
if(is.null(color)) {color = NA}
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
geom_point(color=color)
p
}
I have a custom function that calls ggplot. I'd like to make one of the ggplot arguments optional - for example, changing the color of geom_point. I know two ways to do this, as shown below; one is to specify a default if the optional argument is not provided, and the other is to wrap the whole ggplot function (here, geom_point()
) in an if statement. Neither of these is ideal in my case - the argument I'm using has no easy default, and the ggplot function itself is already in an if/else if/else statement in my code, meaning that I'd end up with a lot of nested if statements. Is there any way to pass an argument saying essentially, "ignore this argument, use your default behavior"?
Here's a very basic example of the two ways that do work:
library(ggplot2)
library(dplyr)
# Opt 1 - specify a default; not viable in my actual problem due to lack of default
fun_default <- function(df, x, y, color="red"){
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
geom_point(color=color)
p
}
# Opt 2 - use an if statement for the whole argument
# workable but cumbersome in my actual problem, since I'd have to repeat the if/else multiple times throughout the code
fun_if <- function(df, x, y, color=NULL){
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
{if(is.null(color)) { geom_point() }
else { geom_point(color = color)}}
p
}
fun_default(mtcars, wt, mpg, color="blue")
fun_if(mtcars, wt, mpg, color="blue")
fun_if(mtcars, wt, mpg)
What I'd like to do is either nest an if statement inside the geom_point call, or set a color argument that would default to whatever ggplot's default is, without specifying the default on my own. In my head this would look something like one of the following (obviously neither of these actually work):
# if statement inside of geom_point()
fun_wish1 <- function(df, x, y, color=NULL){
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
geom_point( {if(!is.null(color)) {color=color}} )
p
}
# somehow tell geom_point to ignore color or use its default for color
fun_wish2 <- function(df, x, y, color=NULL){
if(is.null(color)) {color = NA}
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
geom_point(color=color)
p
}
Share
Improve this question
asked 19 hours ago
JakenJaken
4232 silver badges8 bronze badges
2 Answers
Reset to default 4Consider the ellipsis construct for passing a variable number of arguments:
fun_default <- function(df, x, y, ...){
p <- df %>%
ggplot(aes({{x}}, {{y}})) +
geom_point(...)
p
}
fun_default(mtcars, wt, mpg, color="blue")
fun_default(mtcars, wt, mpg)
1) Set the alpha transparency to 0 if the color is missing if you are trying to avoid showing geom_point
if color is missing.
library(ggplot2)
fun <- function(df, x, y, color = 1) {
ggplot(df, aes({{x}}, {{y}})) +
geom_point(color = color, alpha = !missing(color))
}
# tests
fun(BOD, Time, demand)
fun(BOD, Time, demand, "red")
2) In fun_if
if you are just worried about having an if
in the ggplot geom pipeline then the if
could be outside it.
fun_if2 <- function(df, x, y, color) {
g <- if (missing(color)) geom_point() else geom_point(color = color)
ggplot(df, aes({{x}}, {{y}})) + g
}
In fact it could even be in a separate function:
g.p <- function(color) {
if (missing(color)) geom_point() else geom_point(color = color)
}
fun_if3 <- function(df, x, y, color) {
ggplot(df, aes({{x}}, {{y}})) + g.p(color)
}