如何在ggplot中使用变量指定列名

How to use a variable to specify column name in ggplot

提问人:Theodore Norvell 提问时间:3/11/2014 最后编辑:Gregor ThomasTheodore Norvell 更新时间:10/18/2022 访问量:118377

问:

我有一个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 )
GGPLOT2 NSE R-常见问题解答

评论


答:

240赞 David Robinson 3/11/2014 #1

注意:此答案中的解决方案是“软弃用”。请参阅下面使用 .data[[ 获取当前首选方法的答案。

您可以使用: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) ) )

评论

0赞 smci 6/12/2018
值得一提的是,你不应该/不能这样做,无论如何你不需要,因为你已经通过了论点。(本问题中的问题aes_string(x = rates.by.groups$name...ggplot(data = rates.by.groups...)
8赞 Gregor Thomas 4/4/2019
只需添加一个注释,通过 ggplot2 版本 3.0.0 的更新将人们指向 Moody_Mudskipper 的答案
0赞 David Robinson 7/13/2019
@buncis 这不是真的,引用或行不通"column_name""column"
0赞 buncis 7/15/2019
@DavidRobinson抱歉我的错误,我没有看到代码包装在带有参数的函数上,将删除我的评论
1赞 jessexknight 2/5/2020
“繁琐”?具有讽刺意味的是,R 中的非标准计算是我在编程语言中遇到的最繁琐的“功能”。真是令人抓狂。
18赞 MDe 3/11/2014 #2

尝试使用代替 .aes_stringaes

评论

7赞 mtelesha 6/28/2018
这是一个很好的建议,但你能告诉他们为什么吗?aes_string使你对非变量使用“”,你使用变量取消引号。aes_string(x = “foo”, y = “fee”, group = 变量)
0赞 buncis 7/15/2019
@mtelesha可能是因为变量的值是字符串
106赞 moodymudskipper 11/6/2018 #3

发行说明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)

评论

45赞 CoderGuy123 6/4/2019
这种整洁的东西太烦人了。文档本身就谈到了,但它不起作用。以前谁听说过?大叹息aes()enquo()ensym()
0赞 steveb 8/21/2019
@Moody_Mudskipper 对于 ,所有四个示例都有效,在变量中捕获列名(即 )。如果我添加代码来使用它来操作数据框,则会尝试使用变量名称而不是变量名称中的字符串来查找列。换句话说,我如何开始工作并仍然支持三种通话方式?f2aname <- "mjr"; f2(aname)dplyrrates.by.groups %>% group_by(!!column)...f2
1赞 moodymudskipper 8/21/2019
“在变量中捕获列名也是如此”:它不会失败,但不会返回相同的结果,旨在处理作为名称提供的参数,并容忍它们周围的引号。我相信您希望将参数视为名称,如果找不到该名称,则回退到该值。这实际上是 发生的事情,但不是......可以绕过它,但并不明显。如果它对你很重要,我认为它应该有自己的问题。ensymselectgroup_by
0赞 steveb 8/21/2019
@Moody_Mudskipper谢谢。我同时使用两者,所以这可能是问题所在。我可以创建一个新问题,但我需要想出一个简单的例子,看看它是否已经得到回答。如果没有,我可以发布它。selectgroup_by
1赞 mRiddle 10/20/2019
如何使用!!如果是?它适用于 但抛出错误facet_gridfacet_grid(cols = vars(!!column))facet_grid(~ !!column)
66赞 Tung 4/5/2019 #4

另一个选项 () 是使用整洁的评估代词 .data 从数据框中切取所选变量/列。ggplot2 > 3.0.0rates.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)'))

创建于 2019-04-04 由 reprex 软件包 (v0.2.1.9000)

评论

4赞 dave adelson 4/2/2021
.data[[ ]] 方法最好的地方是它的通用性。谢谢。
5赞 fry 6/24/2021
我相信这是自 rlang 0.4.* 被引入以来的规范解决方案。这也是在ggplot2的官方小插曲中提出的:ggplot2.tidyverse.org/articles/ggplot2-in-packages.html
2赞 Marty999 3/10/2020 #5

使用确实解决了这个问题,但在添加错误栏时确实遇到了一个问题。下面是一个简单的解决方案。aes_stringgeom_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 - 使用自定义函数的误差线

18赞 stevec 8/4/2020 #6

做两件事

  1. 将列名转换为符号sym()
  2. 在要使用符号时在符号前面添加!!

my_col <- sym("Petal.Length")

iris %>% 
  ggplot(aes(x = Sepal.Length, y = !!my_col)) +
  geom_point()