159

我有一个 ggplot 命令

ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )

在一个函数里面。但我希望能够使用函数的参数来挑选出用作颜色和组的列。即我想要这样的东西

f <- function( column ) {
    ...
    ggplot( rates.by.groups, aes(x=name, y=rate, colour= ??? , group=??? ) )
}

这样 ggplot 中使用的列由参数确定。例如对于 f("majr") 我们得到的效果是

ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )

但是对于 f("gender") 我们得到的效果是

  ggplot( rates.by.groups, aes(x=name, y=rate, colour=gender, group=gender) )

我尝试过的一些事情:

ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ) )

不工作。也没有

e <- environment() 
ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ), environment=e )
4

6 回答 6

212

您可以使用aes_string

f <- function( column ) {
    ...
    ggplot( rates.by.groups, aes_string(x="name", y="rate", colour= column,
                                        group=column ) )
}

只要您将列作为字符串(f("majr")而不是f(majr))传递给函数。另请注意,我们将其他列"name"和更改"rate"为字符串。

如果出于某种原因您不想使用aes_string,则可以将其更改为(稍微麻烦一些):

    ggplot( rates.by.groups, aes(x=name, y=rate, colour= get(column),
                                        group=get(column) ) )
于 2014-03-10T19:20:13.927 回答
75

发行说明ggplot2 V3.0.0

aes() 现在支持准引用,因此您可以使用 !!、!!! 和 :=。这取代了现在软弃用的 aes_() 和 aes_string() (但会保留很长时间)。

现在惯用的方法是将变量包含的字符串转换为符号,使用(与基本别名/sym()几乎相同),并使用取消引用它as.name()as.symbol()!!

我们可以模拟 OP 的数据:

library(tidyverse)
rates.by.groups <- data.frame(
  name = LETTERS[1:3],
  rate = 1:3,
  mjr = LETTERS[c(4,4,5)],
  gender = c("M","F","F")
)

f <- function(column) {
  column <- sym(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

f("gender")
f("mjr")
x <- "gender"
f(x)

如果我们宁愿将原始名称提供给函数,我们可以这样做:

f2 <- function(column) {
  column <- ensym(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

它将与名称(即符号)和字符串文字一起使用

f2(gender)
f2(mjr)
f2("gender")
f2("mjr")

正如莱昂内尔所说ensym()

它旨在模仿参数的语法,您可以在 LHS 中同时提供这两个参数,例如 list(bare = 1, "quoted" = 2)


关于enquo()

enquo()引用提供给参数的表达式(不一定是符号),它不会将字符串文字转换为符号,ensym()因此在这里可能不太适合,但我们可以这样做:

f3 <- function(column) {
  column <- enquo(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

f3(gender)
f2(mjr)
于 2018-11-06T08:57:51.763 回答
37

另一个选项 ( ggplot2 > 3.0.0) 是使用 tidy 评估代词.datarates.by.groups数据帧中分割所选变量/列。

library(ggplot2)
theme_set(theme_classic(base_size = 14))

# created by @Moody_Mudskipper
rates.by.groups <- data.frame(
  name = LETTERS[1:3],
  rate = 1:3,
  mjr = LETTERS[c(4, 4, 5)],
  gender = c("M", "F", "F")
)

f1 <- function(df, column) {
  gg <- ggplot(df, 
         aes(x = name, 
             y = rate, 
             fill  = .data[[column]], 
             group = .data[[column]])) +
    geom_col() +
    labs(fill = column)
  return(gg)
}

plot_list <- lapply(list("gender", "mjr"), function(x){ f1(rates.by.groups, x) })
plot_list
#> [[1]]

#> 
#> [[2]]

# combine all plots
library(egg)
ggarrange(plots = plot_list,
          nrow = 2,
          labels = c('A)', 'B)'))

reprex 包(v0.2.1.9000)于 2019 年 4 月 4 日创建

于 2019-04-04T20:07:36.237 回答
17

尝试使用aes_string而不是aes.

于 2014-03-10T19:20:16.417 回答
13

做好这两件事

  1. 将列名转换为符号sym()
  2. !!你想使用它时,在符号前添加它

例子

my_col <- sym("Petal.Length")

iris %>% 
  ggplot(aes(x = Sepal.Length, y = !!my_col)) +
  geom_point()
于 2020-08-04T04:34:44.093 回答
2

使用aes_string确实解决了这个问题,但在添加错误栏时确实会遇到问题geom_errorbar。下面是一个简单的解决方案。

#Identify your variables using the names of your columns indie your dataset
 xaxis   <- "Independent"   
 yaxis   <- "Dependent"
 sd      <- "error"

#Specify error bar range (in 'a-b' not 'a'-'b')
 range   <- c(yaxis, sd)                                #using c(X, y) allows use of quotation marks inside formula
 yerrbar <- aes_string(ymin=paste(range, collapse='-'), 
                       ymax=paste(range, collapse='+'))


#Build the plot
  ggplot(data=Dataset, aes_string(x=xaxis, y=yaxis)) +
    geom_errorbar(mapping=yerrbar, width=15, colour="#73777a", size = 0.5) +
    geom_point   (shape=21)

另外,您还可以使用 ggplot 中的这些行向绘图中添加构面:

facet_grid(formula(paste(Variable1, "~", Variable2)))

这个脚本是从这个原始帖子修改的:ggplot2 - 使用自定义函数的误差线

于 2020-03-09T20:14:26.643 回答