我在函数中有一个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 )
也没有

#1 楼

只要将列作为字符串传递给函数(aes_string而不是f("majr")),就可以使用f(majr)

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


。另请注意,我们将其他列"name""rate"更改为字符串。

如果出于某种原因而不想使用aes_string,则可以将其更改为(比较麻烦): br />
    ggplot( rates.by.groups, aes(x=name, y=rate, colour= get(column),
                                        group=get(column) ) )


评论


值得一提的是,您不应该/不能做aes_string(x = rates.by.groups $ name ...,并且无论如何都不需要,因为您已经通过了ggplot(data = rates.by.groups ...论点(此问题中的问题)

–smci
18年6月12日在3:09



只需添加注释以使人们了解ggplot2 3.0.0版的更新即可了解Moody_Mudskipper的答案

–格雷戈·托马斯(Gregor Thomas)
19年4月4日在15:31

@buncis并非如此,引用“ column_name”或“ column”将不起作用

–大卫·罗宾逊(David Robinson)
19年7月12日在18:32



@DavidRobinson对不起我的错误,我看不到代码包装在带有参数的函数上,会删除我的注释

–蹦极
19年7月15日在7:49

“麻烦”?具有讽刺意味的是,R中的非标准评估是我在编程语言中遇到的最繁琐的“功能”。真是疯了。

– jessexknight
2月4日18:10

#2 楼

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()
}


它将与名称一起使用aka符号和字符串文字

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


正如Lionel所说的ensym()


,它的意思是模仿参数的语法,其中您可以在LHS中同时提供
,例如list(裸= 1,“带引号” = 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)


评论


这种tidyeval的东西太烦人了。 aes()的文档本身讨论了enquo(),但它不起作用。谁曾听说过ensym()?大SIGH

– CoderGuy123
19年4月4日14:37



@Moody_Mudskipper对于f2,所有四个示例均有效,在变量中捕获列名称也是如此(即aname <-“ mjr”; f2(aname))。如果添加代码以使用dplyr操纵数据框,它将尝试使用变量名而不是变量名中的字符串查找列。换句话说,我如何使rates.by.groups%>%group_by(!! column)...能够正常工作并仍支持调用f2的三种方式?

–steveb
19年8月20日在21:42

“捕获变量中的列名也是如此”:它不会失败,但不会返回相同的结果,ensym旨在处理作为名称提供的参数,并允许在它们周围加上引号。我相信您希望将参数视为一个名称,如果找不到该名称,则使用该值。这实际上是select发生的情况,而group_by则没有。。。可以绕开它,但并不明显。如果它对您很重要,我认为这应该得到自己的问题。

– Moody_Mudskipper
19年8月20日在23:09

@Moody_Mudskipper谢谢。我同时使用了select和group_by,所以这可能是问题所在。我可以创建一个新问题,但是我需要拿出一个简单的示例并检查是否已回答。如果没有,我可以发布。

–steveb
19年8月21日在1:17

如何使用 !!如果是facet_grid?它与facet_grid(cols = vars(!! column))一起使用,但与facet_grid(〜!! column)引发错误

–mRiddle
19-10-20在6:57

#3 楼

尝试使用aes_string而不是aes

评论


这是很好的建议,但是您能告诉他们为什么吗? aes_string使您对非变量使用“”,而对变量使用无引号。 aes_string(x =“ foo”,y =“ fee”,group =变量)

–mtelesha
18年6月27日在18:32

@mtelesha可能是因为变量将字符串作为其值

–蹦极
19年7月15日在12:43

#4 楼

另一个选择(ggplot2 > 3.0.0)是使用整齐的评估代词.data来从rates.by.groups数据帧中切片所选的变量/列。 prettyprint-override“> 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 reprex软件包(v0.2.1.9000)-04-04

#5 楼

这是一种非常简单的方法!
执行以下两项操作:

使用sym()将列名转换为符号

使用时添加!!

可重现性最小的示例:
my_col <- sym("Petal.Length")

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


#6 楼

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

奖励,您还可以使用ggplot内的以下线在绘图中添加构面:

#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)


此脚本是从原始帖子中修改的:ggplot2-使用自定义功能的错误栏