非标准评估,lapply和ggplot

5

我正在尝试使用ggplot2编程绘制分布图。

我无法弄清楚如何在这里使用非标准评估(NSE)(即使在阅读了Hadley的书章节等关于NSE的内容之后)。

请考虑以下代码:

library(ggplot2)


gg_dens <- function(x){
  eval(ggplot(data.frame(x), aes_string(x = substitute(x))) + geom_density() +
         ggtitle(substitute(x)), data.frame(x))
}


lapply(mtcars, function(x) gg_dens(x))

这段代码确实生成了多个密度图,每一列都有一个。但是,它没有打印出正在绘制的变量名称。相反,印出了占位符变量 x(参见图)。

plot resulting from code above

我的目标是将 x 引号替换为实际的变量名,例如,mpg


谢谢Richard,但对我不起作用。 - Sebastian Sauer
1
你只是在试验吗(例如,这是一个学习练习)?如果不是,aes_string()可以大大帮助变量替换。 - hrbrmstr
3
lapply 循环中的 x 是一个无名原子向量。它没有名称可以用于 substitute - LyzandeR
定义函数为 gg_dens <- function(myData, myCol){...},然后使用 aes_string 来处理 myCol,同时将其用于绘图标题,这样不是更好吗? - zx8754
1
根据@zx8754的评论,您可以尝试类似于mapply(gg_dens, df, colnames(df))的东西,而函数定义为gg_dens <- function(data, title){} - Roman
2个回答

1
你可以尝试:

gg_dens <- function(x, y){
  ggplot(y, aes_(x = as.name(colnames(y)[x]))) + geom_density() + ggtitle(colnames(y)[x])
}

lapply(1:ncol(mtcars), gg_dens, mtcars)

这段内容的翻译如下:

这个想法是循环遍历列索引。 aes_as.name 一起将字符串转换为名称。


1

lapply不能使用您当前拥有的函数来解决这个问题。当传递给该函数时,x只是一个向量,而不是该变量的名称,lapply没有传递任何作为名称的东西。换句话说,在该函数的范围内没有任何内容可以让它确定应该是正确的x轴标签。

一个解决方案类似于@Jimbou:

gg_dens <- function(name, dat) {
  ggplot(dat, aes_string(x = name)) + geom_density() + ggtitle(name)
}    
lapply(names(mtcars), gg_dens, mtcars)

或者直接使用facets:

mtcars2 <- tidyr::gather(mtcars)
ggplot(mtcars2, aes(value)) + geom_density() + facet_wrap(~key, scales = 'free')

1
谢谢@Axeman,问题已解决。我现在更好地理解了NSE和ggplot。 - Sebastian Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接