R包tidy eval应用:stacked_plot函数内部调用报错问题
解决包内函数调用tidy eval堆叠图函数的报错问题
问题根源
你遇到的错误是因为rlang::ensym()只能接受**符号(比如v1)或字符串(比如"v1")**作为输入,但你在call_plot里传入的.data$v1是一个.data代词的调用表达式,并非符号/字符串,因此ensym()无法完成转换,抛出了"Only strings can be converted to symbols"的错误。
解决方案:替换ensym为enquo并使用curly-curly语法
我们需要修改stacked_plot函数,改用rlang::enquo()来捕获任意表达式(包括.data$xxx这种代词调用),同时用更简洁的{{ }}(curly-curly操作符)完成插值。以下是修改后的完整函数:
stacked_plot <- function(data, what, by = NULL, date_col = date){ # 捕获所有参数的表达式(包括.data$xxx这类) by <- rlang::enquo(by) what <- rlang::enquo(what) date_col <- rlang::enquo(date_col) data <- data %>% dplyr::group_by(!!date_col, !!by) %>% # 提取what的变量名用于赋值,同时计算求和 dplyr::summarise( !!rlang::as_name(what) := sum({{what}}, na.rm = TRUE), .groups = "drop" # 替代ungroup(),更简洁 ) %>% tidyr::complete( !!date_col, !!by, fill = rlang::list2(!!rlang::as_name(what) := 0) ) p <- data %>% ggplot2::ggplot(ggplot2::aes({{date_col}}, {{what}}, fill = {{by}})) + ggplot2::geom_area(position = 'stack') print(p) invisible(p) # 返回绘图对象但避免重复打印 }
如果你想进一步简化代码,可以省略手动enquo的步骤,直接用{{ }}替代!!enquo()的组合({{x}}等价于!!rlang::enquo(x)):
stacked_plot <- function(data, what, by = NULL, date_col = date){ # 提前捕获what的表达式,用于提取变量名 what_quo <- rlang::enquo(what) what_name <- rlang::as_name(what_quo) data <- data %>% dplyr::group_by({{date_col}}, {{by}}) %>% dplyr::summarise( !!what_name := sum({{what}}, na.rm = TRUE), .groups = "drop" ) %>% tidyr::complete( {{date_col}}, {{by}}, fill = rlang::list2(!!what_name := 0) ) p <- data %>% ggplot2::ggplot(ggplot2::aes({{date_col}}, {{what}}, fill = {{by}})) + ggplot2::geom_area(position = 'stack') print(p) invisible(p) }
关键修改说明
- 用
enquo替代ensym:enquo()可以捕获任意R表达式,包括.data$xxx这种代词调用,完美适配包内函数调用时的.data规范(避免R CMD check的"无可见绑定"警告)。 - 提取变量名用于赋值:在
summarise和complete的fill参数中,我们需要用rlang::as_name()从捕获的表达式中提取原始变量名,保证结果数据框的列名和输入一致。 - curly-curly语法简化插值:
{{ }}是!!enquo(x)的语法糖,让代码更简洁易读,同时保持tidy eval的灵活性。 - 返回绘图对象:加入
invisible(p)确保函数返回ggplot对象的同时,不会在非交互式调用时重复打印图形。
测试修改后的代码
现在执行call_plot()就能正常生成堆叠图了,不管是交互式调用还是包内load_all()后的调用都不会报错。
内容的提问来源于stack exchange,提问作者Kuba_
相关产品推荐
相关产品推荐

