我正在尝试编写一个绘图函数,您可以在其中传递裸列名称以选择要绘制的列。我还希望能够指定一个字符串作为颜色。
我发现如果要将字符串传递给aes_string,则需要使用shQuote。现在我的问题是找出是否传递了裸名或字符串。
我该怎么做?
dat <- data.frame(
time = factor(c("Lunch","Dinner"), levels=c("Lunch","Dinner")),
total_bill = c(14.89, 17.23)
)
plot_it <- function(dat, x,y, fill){
require(rlang)
require(ggplot2)
x <- enquo(x)
y <- enquo(y)
fill <- enquo(fill)
xN <- quo_name(x)
yN <- quo_name(y)
fillN <- quo_name(fill)
ggplot(data=dat, aes_string(x=xN, y=yN, fill=fillN)) +
geom_bar(stat="identity")
}
这有效:
plot_it(dat, time, total_bill, time)
这不是:
plot_it(dat, time, total_bill, "grey")
请注意,这需要最新版本的rlang和ggplot2。
最佳答案
从your answer和Eumenedies' answer/test cases工作,这是一个版本:
geom_col
主要技巧是,如果
fill
不是情节中的一个因素,则您希望将其放在aes
/aes_string
块之外。plot_it <- function(dat, x, y, fill) {
lst <- as.list(match.call())
xN <- quo_name(enquo(x))
yN <- quo_name(enquo(y))
if(is.character(lst$fill)) {
p <- ggplot(data=dat, aes_string(x=xN, y=yN)) +
geom_col(fill = fill)
} else {
p <- ggplot(data=dat, aes_string(x=xN, y=yN, fill = quo_name(enquo(fill)))) +
geom_col()
}
return(p)
}
plot_it(dat, time, total_bill, time)
plot_it(dat, time, total_bill, "blue")
plot_it(dat, time, total_bill, "blue") + geom_point()
您可以通过将第二种情况下的
if
美感移至fill
调用来缩短geom_col
块,但是如果添加更多几何,则会以不同的方式扩展。另外,一旦
ggplot
更新为支持rlang
,避免使用aes_string
和quo_name
组合会更清洁,而只需使用!!fill
即可。请注意,假设存在
fill
因子,如果它始终与x
因子相同,那么使用fill
是可选参数的版本可能更有意义。如果包含该参数,则仅覆盖默认的每个因数颜色。关于r - 如何检测裸变量或字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43974780/