我想创建一个绘图函数,我在其中指定数据集,并以类似的方式将绘图参数指定为函数参数ggplot2
,即我们在没有数据集的情况下指定变量名称,例如hp
代替mtcars$hp
.
例如:
ggfun <- function(dat, x.var, 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)
Run Code Online (Sandbox Code Playgroud)
然而它返回:
> ggfun(dat = mtcars, x.var = drat, y.var = hp)
Error in eval(expr, envir, enclos) : object 'drat' not found
In addition: Warning message:
In eval(expr, envir, enclos) : restarting interrupted promise evaluation
Run Code Online (Sandbox Code Playgroud)
我知道使用aes_string
而不是aes
作品,例如:
ggfun <- function(dat, x.var, y.var){
ggp <- ggplot(data = dat,
aes_string(x = x.var,
y = y.var)) +
geom_point()
return(ggp)
}
ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
Run Code Online (Sandbox Code Playgroud)
但我宁愿避免使用字符串形式.
其他尝试包括ggfun(dat = mtcars, x.var = mtcars$drat, y.var = mtcars$hp)
,它返回正确的图形但部分地违背了练习的目的,并产生标签"x.var"和"y.var"而不是"drat"和"hp".
任何已知且相当简单的方法?
akr*_*run 13
使用devel版本ggplot2
,我们可以传递不带引号的参数,将其转换为quosure
(with enquo
)并对其进行求值(!!
)
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)
Run Code Online (Sandbox Code Playgroud)
对于带引号的字符串,使用sym
(from rlang
)将其转换为符号并进行评估
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")
Run Code Online (Sandbox Code Playgroud)
如果我们想要传递引用或不引用,则将quosure更改为character(quo_name
),然后更改为symbol(sym
)和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
Run Code Online (Sandbox Code Playgroud)
从rlang
0.4.0 (2019-06-25) 开始,现在有了拥抱运算符 {{}}
。使用拥抱运算符:
library(ggplot2)
data("mtcars")
Run Code Online (Sandbox Code Playgroud)
该运算符适用于函数参数中的列名称和标签。
scatter_plot <- function(data, x, y, title) {
ggplot(data, aes({{x}}, {{y}})) +
geom_point()+
labs(title= {{title}})
}
Run Code Online (Sandbox Code Playgroud)
scatter_plot(mtcars, drat, hp, "Drat by HP")
Run Code Online (Sandbox Code Playgroud)
+
可以像平常一样进一步定制绘图。
scatter_plot(mtcars, drat, hp, "Drat by HP with trend") +
geom_smooth()
Run Code Online (Sandbox Code Playgroud)