You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R自定义函数中向ggpubr传递变量时报错的解决方法

解决dplyr分组汇总+ggpubr绘图函数封装的引号问题

问题描述

我想把以下包含dplyr分组汇总与ggpubr绘图的代码封装为函数:

df %>% 
  group_by(a, b) %>%
  summarize(avg=mean(c)) %>%
  ggline(x="a", y="avg", color='b')

但调用自定义函数时,尽管is.factor(df$b) == TRUE,仍返回错误:Error in is.factor(x) : object 'b' not found。自定义函数代码如下:

graph_var <- function(data_source, var) {
  var2 <- enquo(var)
  
  data_source %>% 
    group_by(a, !!var2 )%>% 
    summarize(avg=mean(c)) %>% 
    ggline(x="a", y="avg", color=shQuote(var) )+ grids(linetype = 'dashed')
}

graph_var(df, b)

可复现代码

library(tidyverse)
library(ggpubr)

set.seed(13)
df <- data.frame(
  a = rep(1:10),
  b = as.factor(rep(LETTERS[24:26], each = 10)),
  c = rnorm(30)
)

# 显式声明 - 可正常运行
df %>% 
  group_by(a, b )%>% 
  summarize(avg=mean(c)) %>% 
  ggline(x="a", y="avg", color="b" )+ grids(linetype = 'dashed') # works

# 通过变量传递 - 也可正常运行
test_var <- "b"

df %>% 
  group_by(a, b )%>% 
  summarize(avg=mean(c)) %>% 
  ggline(x="a", y="avg", color=test_var )+ grids(linetype = 'dashed') # also works

# 通过函数声明 - 返回错误"Error in is.factor(x) : object 'b' not found"
graph_var_ex <- function(data_source, var) {
  var2 <- enquo(var)
  
  data_source %>% 
    group_by(a, !!var2 )%>% 
    summarize(avg=mean(c)) %>% 
    ggline(x="a", y="avg", color=shQuote(var) )+ grids(linetype = 'dashed')
}

graph_var_ex(df, b)

问题原因

错误出在shQuote(var)的使用上:

  • 当传入b作为参数时,var是一个符号对象,shQuote(var)会将其转换为带单引号的字符串(即"'b'")。
  • ggpubr的color参数需要的是不带额外引号的列名字符串,此时它会尝试在数据框中寻找列名为'b'(包含单引号)的列,而实际列名是b,因此报错找不到对象。

解决方案

需要将传入的符号参数转换为纯净的列名字符串,而不是带额外引号的版本。可以用rlang::as_name()处理enquo()生成的quosure对象,得到正确的列名字符串。

修正后的函数

graph_var_ex <- function(data_source, var) {
  var2 <- enquo(var)
  # 将quosure转换为列名字符串
  var_colname <- rlang::as_name(var2)
  
  data_source %>% 
    group_by(a, !!var2 )%>% 
    summarize(avg=mean(c)) %>% 
    ggline(x="a", y="avg", color=var_colname )+ grids(linetype = 'dashed')
}

简化版(使用{{}}语法)

如果想简化tidyeval的写法,可以用{{}}(curly-curly)代替enquo()和!!,同时获取列名字符串:

graph_var_ex <- function(data_source, var) {
  var_colname <- rlang::as_name(rlang::enquo(var))
  
  data_source %>% 
    group_by(a, {{var}} )%>% 
    summarize(avg=mean(c)) %>% 
    ggline(x="a", y="avg", color=var_colname )+ grids(linetype = 'dashed')
}

测试

调用修正后的函数即可正常运行:

graph_var_ex(df, b)

内容的提问来源于stack exchange,提问作者Trevor Sutherland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:40:53