I am trying to write a function that creates plots and ran into an error that I don't understand. Here is a simplified example.
Reproducible example:
library (ggplot2)
# Sample data
xdata = 0:20
ydata = 20:40
dat <- data.frame(xdata, ydata)
# This works
line_p <- ggplot(dat, aes(x = xdata, y = ydata, group = NULL, color = NULL)) + geom_line()
line_p
I expected the following to work, but get an aesthetics error, but in this case the x and y variables are the same length. The issues seems to be having a default value of NULL for group and color. I tried explicitly passing NULL as well with aes_group and aes_color as function variables but this also did not work.
# Using a function doesn't work:
# create function
line_function <- function(mydata = dat,
xinput = x,
yinput = y,
aes_group = NULL,
aes_color = NULL,
...) {
lineplot <- ggplot(dat, aes(x = xinput, y = yinput, group = aes_group, color = aes_color)) + geom_line()
}
# test the function
line_test_p <- line_function(
mydata = dat,
xinput = xdata,
yinput = ydata
)
line_test_p
Testing with explicit inputs
# test the function again with explicit NULL inputs
line_test2_p <- line_function(
mydata = dat,
xinput = xdata,
yinput = ydata,
aes_group = NULL,
aes_color = NULL
)
line_test2_p
Is it not possible to write a generic function where ggplot will interpret the NULL values as in the example that works without a function, or am I missing something else?
Thanks!
In short, you should check out aes_string
for creating aesthetic mappings programmatically. It allows you to create aesthetic mappings using the names of variables stored strings. That way, it's easy to pass column names as arguments to a function and create the corresponding plot.
The following version of your function works for me:
# create function
line_function <- function(mydata = dat,
xinput = "x", # note the defaults are
yinput = "y", # strings here
aes_group = NULL,
aes_color = NULL,
...) {
ggplot(mydata, # this should be the argument, not the global variable dat
# now we create the aes binding with aes_string
aes_string(x = xinput,
y = yinput,
group = aes_group,
color = aes_color)) +
geom_line()
}
And now you can use the function to create your examples:
# test the function
line_test_p <- line_function(
mydata = dat,
xinput = "xdata", # note the strings
yinput = "ydata"
)
# test the function again with explicit NULL inputs
line_test2_p <- line_function(mydata = dat,
xinput = "xdata", # and strings here
yinput = "ydata",
aes_group = NULL,
aes_color = NULL)
And things should work out for you. Again, do check out the documentation, because there are different ways you can accomplish this, and you may prefer different ways for different purposes or preferences.