R - How to pass variables to ggplot
Using of aes_string
is deprecated, you can use sym
with !!
:
library(ggplot2)
library(rlang)
scatterWithRegLine = function(df, xColName, yColName, regMethod, showSe, showFullrange, size, yAxisLim) {
ggplot(df, aes(x = !!sym(xColName), y = !!sym(yColName))) +
geom_point() +
geom_smooth(method= regMethod, se=showSe, fullrange=showFullrange, size=size) + ylim(yAxisLim)
}
and then call it with
scatterWithRegLine(mtcars, "mpg", "wt", "loess", TRUE, FALSE, 1, c(0,5))
R ggplot2 - Understanding the parameters of the aes function
Consider the code chunk below:
library(ggplot2)
df <- data.frame(
x = c(1, 2), y = c(2, 1)
)
ggplot(df, aes(x, y + 1)) +
geom_point(colour = "green") +
geom_line(aes(colour = "blue"))
Here, the aes(x, y + 1)
means aes(x = x, y = y + 1)
which sets the x
and y
aesthetics that some layers understand to the x
and y
columns of the dataframe. This is because aes()
has three arguments, x
, y
and ...
. By not declaring x = x
for example, the first variable x
is matched to the x
parameter through the position in the function call. Other parameters than x
or y
must be named, for example aes(size = 10)
and get passed trough ...
to become part of the mapping (which are name-expression pairs).
Because the expression y = y + 1
is evaluated using 'non standard evaluation' in aes()
, the scoping rules change and the variable y
will first be attempted to be evaluated in the context of the data columns and not in the global environment, and hence we can 'calculate' the +1
on the dataframe columns.
It's not the aes()
function that determines what are valid argument = value
mappings, it is the layers that accept or reject parameters. You can find the parameters a layer accepts in the documentation of the layer, for example in ?geom_point
, you see that it understands x
, y,
alpha
, colour
, fill
, group
, shape
, size
and stroke
. You should be able to find these back if you call your_geom_layer$geom$aesthetics()
. Extension packages can define their own layers with their own aesthetics, such as the area
in the {treemap} package.
Additionally, because we've defined aes(x, y + 1)
in the main ggplot()
call, it will applied to every geometry or stat layer in that plot, in this case the points and the line. Hence, we do not need to repeat the same mapping in every layer but it is inherited unless you set inherit.aes = FALSE
in a layer.
In the point layer we've defined colour = "green"
outside the aes()
function, so it will be interpreted literally (and follows standard evaluation with the usual scoping rules). People also call this a 'static' mapping, and you can only use this in layers and not globally. In contrast, because we've defined aes(colour = "blue")
in the line layer, the "blue"
will be interpreted as a categorical variable that participates in a colour scale that has it's own palette (a 'dynamic' mapping). If you execute the code, you'll see that the line is not blue, but a salmon-ish colour with a legend that maps the categorical value "blue" to a discrete scale with a 1-colour palette. Because "blue"
is not a column in the dataframe, nor a variable in the global environment, it will be interpreted as a length 1 vector that will be recycled to fit the number of rows in the dataframe.
In general, if you want to map something to a scale (including position scales such as x
and y
), you put it inside aes()
. If you want to have a literal interpretation, you put it outside aes()
at the relevant layer.
passing parameters to ggplot
One solution would be to pass x and y as string names of columns in data frame DS.
f <- function(DS, x, y) {
ggplot(DS, aes_string(x = x, y = y)) + geom_point()
}
And then call the function as:
f(cars, "speed", "dist")
However, it seems that you don't want that? Can you provide an example why you would need different functionality? Is it because you don't want to have the arguments in the same data frame?
R: How to pass parameters to ggplot geom_ within a function?
I like MSM's approach, but if you want to be able to add my_geom_y
to a ggplot you've already made, this is an alternative that might suit what you're after:
library(ggplot2)
x <- 1:100
my_geom_y <- function(yy, colour = "black"){
list(
geom_line(mapping = aes(y= yy),
col = colour),
data = data.frame(x, yy),
geom_point(mapping = aes(y = yy),
col = colour,
data = data.frame(x, yy))
)
}
ggplot(mapping = aes(x)) +
my_geom_y(x, "red") +
my_geom_y(dlnorm(x), "blue") +
my_geom_y((x^1.1), "black") +
my_geom_y(x/2, "yellow")
R- pass argument to ggplot in function
Based on the function arguments, it seems like convert
is flip
. Instead of using get
to modify the 'x' argument, we can do this with mutate
after converting the arguments to quosures
myfunction<- function(mydata, x, y, convert = FALSE){
x <- enquo(x)
y <- enquo(y)
xnew <- quo_name(x)
if (convert) {
mydata %>%
mutate(!! (xnew) := 1- !!(x)) %>%
ggplot(., aes_string(xnew, quo_name(y))) +
geom_line() +
xlab(paste0("1 - ", xnew))
} else {
ggplot(mydata, aes_string(xnew, quo_name(y))) +
geom_line()
}
}
myfunction(df1, x1, x2, convert = TRUE)
-output
myfunction(df1, x1, x2, convert = FALSE)
-output
data
df1 <- structure(list(x1 = c(0.1, 0.3, 0.4), x2 = c(0.2, 0.5, 0.6),
x3 = c(0.3, 0.7, 0.8), x4 = c(0.4, 0.9, 0.2)), .Names = c("x1",
"x2", "x3", "x4"), class = "data.frame", row.names = c(NA, -3L
))
Create ggplot2 function and specify arguments as variables in data as per ggplot2 standard functionality
With the devel version of ggplot2
, we can pass unquoted arguments, convert it to quosure
(with enquo
) and evaluate it (!!
)
ggfun <- function(dat, x.var, y.var){
x.var <- enquo(x.var)
y.var <- enquo(y.var)
ggp <- ggplot(data = dat,
aes(x = !! x.var,
y = !! y.var)) +
geom_point()
return(ggp)
}
ggfun(dat = mtcars, x.var = drat, y.var = hp)
For quoted strings, convert it to symbol with sym
(from rlang
) and do the evaluation
ggfun <- function(dat, x.var, y.var){
x.var <- rlang::sym(x.var)
y.var <- rlang::sym(y.var)
ggp <- ggplot(data = dat,
aes(x = !! x.var,
y = !! y.var)) +
geom_point()
return(ggp)
}
ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
If we want to pass either quoted or unquoted, the quosure is changed to character (quo_name
), then to symbol (sym
) and evaluate (!!
)
ggfun <- function(dat, x.var, y.var){
x.var <- rlang::sym(quo_name(enquo(x.var)))
y.var <- rlang::sym(quo_name(enquo(y.var)))
ggp <- ggplot(data = dat,
aes(x = !! x.var,
y = !! y.var)) +
geom_point()
return(ggp)
}
p1 <- ggfun(dat = mtcars, x.var = drat, y.var = hp)
p2 <- ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
all.equal(p1, p2)
#[1] TRUE
ggplot2 pass variable to plot to a function
Use aes_string
for this kind of programming:
library(ggplot2)
plothist <- function(data, column) {
ggplot(data, aes_string(x = column)) + geom_histogram()
}
plothist(data, "fixed.acidity")
Related Topics
Integrate a Very Peaked Function
Updating a Subset of a Dataframe
R - Delete Consecutive (Only) Duplicates
Rename Columns Using 'Starts_With()' Where New Prefix Is a String
Directly Adding Titles and Labels to Visnetwork
R: Scatter Plot Matrix Using Ggplot2 with Themes That Vary by Facet Panel
How to Use More Than 2 Colors in the Color_Tile Function
Dual Y Axis (Second Axis) Use in Ggplot2
In R, How to Suppress "Note: No Visible Binding for Global Variable"
Shiny Promises Future Is Not Working on Eventreactive
Generating a Color Legend with Shifted Labels Using Ggplot2
Italic Greek Letters in R Plot
Use Lapply for Multiple Regression with Formula Changing, Not the Dataset
Order of Dates Is Not Chronological in Ggplot2
Extract Date Elements from Posixlt and Put into Data Frame in R
\Sexpr{} Special Latex Characters ($, &, %, # etc.) in .Rnw-File