我正在尝试编写一个绘图函数,您可以在其中传递裸列名称来选择绘制哪些列。我还希望能够指定一个字符串作为颜色。
我发现如果我想将字符串传递给 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。
最佳答案
根据@akrun 关于如何检测我们有(已删除)哪个案例的建议,我发现了一些可以满足我要求的东西:
plot_it <- function(dat, x, y, fill) {
lst <- as.list(match.call())
if(is.character(lst$fill)){
fillN <- shQuote(fill)
} else{
fillN <- quo_name(enquo(fill))
}
x <- enquo(x)
y <- enquo(y)
xN <- quo_name(x)
yN <- quo_name(y)
p <- ggplot(data=dat, aes_string(x=xN, y=yN, fill=fillN)) +
geom_bar(stat="identity")
return(p)
}
事实证明这实际上并不符合我的想法,因为它将引用的值分配为分配颜色的因素。不是实际颜色。
我想出了这个似乎有效但并不优雅的方法:
plot_it <- function(dat, x, y, fill) {
lst <- as.list(match.call())
if(!(type_of(lst$fill)=="symbol" | (type_of(lst$fill)=="string" & length(lst$fill)==1))) stop("Fill must either be a bare name or a vector of length 1.")
x <- enquo(x)
y <- enquo(y)
xN <- quo_name(x)
yN <- quo_name(y)
if(is.character(lst$fill)){
dat[,"fillN"] <- fill
fillN <- fill
p <- ggplot(data=dat, aes_string(x=xN, y=yN, fill = shQuote(fillN))) +
scale_fill_manual(name="fill", values=setNames(fillN,fillN))
} else{
fillN <- quo_name(enquo(fill))
p <- ggplot(data=dat, aes_string(x=xN, y=yN, fill = fillN))
}
p <- p + geom_bar(stat="identity")
return(p)
}
有没有办法让它更优雅一点?
关于r - 如何检测是否为裸变量或字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43974780/