在函数-ggplot中将参数传递给构面网格

Posted

技术标签:

【中文标题】在函数-ggplot中将参数传递给构面网格【英文标题】:Passing argument to facet grid in function -ggplot 【发布时间】:2019-03-16 14:57:01 【问题描述】:

我正在尝试编写一个函数来在网格中绘制图形。我正在使用 ggplot 和构面网格。我无法通过分面网格的论点。我想知道是否有人能指出我正确的方向。

数据示例:

 Year = as.factor(rep(c("01", "02"), each = 4, times = 1))
 Group = as.factor(rep(c("G1", "G2"), each = 2, times = 2))
 Gender = as.factor(rep(c("Male", "Female"),   times = 4))
 Percentage = as.integer(c("80","20","50","50","45","55","15","85"))
 df1 = data.frame (Year, Group, Gender, Percentage)

不带函数的网格图代码为:

p = ggplot(data=df1, aes(x=Year, y=Percentage, fill = Gender)) + geom_bar(stat = "identity")
p = p +  facet_grid(~ Group, scales = 'free')  
p

这会产生一个像我想要做的情节。但是,当我把它放到一个函数中时:

MyGridPlot <- function (df, x_axis, y_axis, bar_fill, fgrid)
p = ggplot(data=df1, aes(x=x_axis, y=y_axis, fill = bar_fill)) + geom_bar(stat = "identity")
p = p +  facet_grid(~ fgrid, scales = 'free')  
return(p)

然后运行:

MyGridPlot(df1, df1Year, df1$Percentage, df1$Gender, df1$Group)

出现错误:

Error: At least one layer must contain all faceting variables: `fgrid`.
* Plot is missing `fgrid`
* Layer 1 is missing `fgrid

我尝试过使用aes_string,它适用于 x、y 和填充,但不适用于网格。

MyGridPlot <- function (df, x_axis, y_axis, bar_fill, fgrid)
p = ggplot(data=df1, aes_string(x=x_axis, y=y_axis, fill = bar_fill)) + geom_bar(stat = "identity")
p = p +  facet_grid(~ fgrid, scales = 'free')  
return(p)

然后运行:

MyGridPlot(df1, Year, Percentage, Gender, Group)

这会产生同样的错误。如果我删除构面网格,两个函数代码都运行良好,虽然没有网格:-(

非常感谢您帮助这个初学者。

古斯塔沃

【问题讨论】:

一些关于如何使用 tidyeval 和 facets here 的好信息。 谢谢!这真的很有帮助。 【参考方案1】:

您的问题是,在您的函数中,ggplot 正在寻找变量名称(x_axisy_axis 等),但您给它的是对象(df1$year...)。

有几种方法可以解决这个问题。也许最简单的方法是重写函数以使其需要对象。例如:

MyGridPlot <- function(x_axis, y_axis, bar_fill, fgrid) # Note no df parameter here
  df1 <- data.frame(x_axis = x_axis, y_axis = y_axis, bar_fill = bar_fill, fgrid = fgrid) # Create a data frame from inputs
  p = ggplot(data=df1, aes(x=x_axis, y=y_axis, fill = bar_fill)) + geom_bar(stat = "identity")
  p = p +  facet_grid(~ fgrid, scales = 'free')  
  return(p)


MyGridPlot(Year, Percentage, Gender, Group)

或者,您可以使用数据框和变量名称设置函数。如果您以这里的方式处理单个对象,则没有太多理由这样做,但如果您使用数据框,它可能会让您的生活更轻松:

MyGridPlot <- function(df, x_var, y_var, fill_var, grid_var)
  # Need to "tell" R to treat parameters as variable names.
  df <- df %>% mutate(x_var = UQ(enquo(x_var)), y_var = UQ(enquo(y_var)), fill_var = UQ(enquo(fill_var)), grid_var = UQ(enquo(grid_var)))

  p = ggplot(data = df, aes(x = x_var, y = y_var, fill = fill_var)) + geom_bar(stat = "identity")
  p = p +  facet_grid(~grid_var, scales = 'free')  
  return(p)


MyGridPlot(df1, Year, Percentage, Gender, Group)

【讨论】:

请注意:?UQ UQ() 和 UQS() 在 rlang 0.2.0 中被软性弃用,以使 quasiquotation 的语法更加一致。前缀形式现在是!!() 和!!!(),这与其他R 运算符一致(例如+(a, b) 是a + b 的前缀形式)。 而且我认为你不需要在函数中引入额外的计算:df &lt;- df %&gt;% mutate(x_var = UQ(enquo(x_var)), y_var = UQ(enquo(y_var)), fill_var = UQ(enquo(fill_var)), grid_var = UQ(enquo(grid_var)))

以上是关于在函数-ggplot中将参数传递给构面网格的主要内容,如果未能解决你的问题,请参考以下文章

如何在firebase函数中将参数传递给cors

在Python中将多个参数传递给pool.map()函数[重复]

在 boost::thread 中将参数传递给函数

如何在一个条目中将RGB作为单独的参数传递给函数

如何在反应测试库中将参数传递给 getByText?

在python 3中将参数传递给exec