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

如何在ggformula包中使用引用变量(替代ggplot的aes_string)

在ggformula中实现动态变量映射(替代ggplot的aes_string)

问题重现

我可以在ggplot中使用aes_string实现动态美学映射,但不知道如何在ggformula包中实现类似功能。以下测试代码运行时出现object 'Species' not found错误:

pacman::p_load(ggformula)
plot_list = list()
names_y_axis = names(iris)[2:4]
plot_list = lapply(names_y_axis, \(x){
  gf_point(Sepal.Length ~ x, color = ~ Species)
})
gridExtra::grid.arrange(grobs = plot_list)

错误信息:

Error in `FUN()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 1st layer.
Caused by error in `FUN()`:
! object 'Species' not found
Backtrace:
     ▆
  1. ├─gridExtra::grid.arrange(grobs = plot_list)
  2. │ └─gridExtra::arrangeGrob(...)
  3. │   └─base::lapply(grobs[toconv], ggplot2::ggplotGrob)
  4. │     └─ggplot2 (local) FUN(X[[i]], ...)
  5. │       ├─ggplot2::ggplot_gtable(ggplot_build(x))
  6. │       │ └─ggplot2:::attach_plot_env(data$plot$plot_env)
  7. │       │   └─base::options(ggplot2_plot_env = env)
  8. │       ├─ggplot2::ggplot_build(x)
  9. │       └─ggplot2:::ggplot_build.ggplot(x)
 10. │         └─ggplot2:::by_layer(...)
 11. │           ├─rlang::try_fetch(...)
 12. │           │ ├─base::tryCatch(...)
 13. │           │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
 14. │           │ │   └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
 15. │           │ │     └─base (local) doTryCatch(return(expr), name, parentenv, handler)
 16. │           │ └─base::withCallingHandlers(...)
 17. │           └─ggplot2 (local) f(l = layers[[i]], d = data[[i]])
 18. │             └─l$compute_aesthetics(d, plot)
 19. │               └─ggplot2 (local) compute_aesthetics(..., self = self)
 20. │                 └─ggplot2:::scales_add_defaults(...)
 21. │                   └─base::lapply(aesthetics[new_aesthetics], eval_tidy, data = data)
 22. │                     └─rlang (local) FUN(X[[i]], ...)
 23. └─base::.handleSimpleError(...)
 24.   └─rlang (local) h(simpleError(msg, call))
 25.     └─handlers[[1L]](cnd)
 26.       └─cli::cli_abort(...)
 27.         └─rlang::abort(...)

解决方案

ggformula基于tidy eval语法,可通过两种方式实现动态变量映射:

方法1:使用rlang的符号与非标准求值

将字符串变量转为符号,再用!!强制求值,同时显式指定数据源data = iris确保变量能被正确识别:

pacman::p_load(ggformula, gridExtra)
plot_list = list()
names_y_axis = names(iris)[2:4]
plot_list = lapply(names_y_axis, \(x){
  y_var <- rlang::sym(x)
  gf_point(Sepal.Length ~ !!y_var, color = ~ Species, data = iris)
})
grid.arrange(grobs = plot_list)

方法2:构造公式字符串转成公式对象

直接拼接公式字符串,再转为公式对象传入gf_point:

pacman::p_load(ggformula, gridExtra)
plot_list = list()
names_y_axis = names(iris)[2:4]
plot_list = lapply(names_y_axis, \(x){
  plot_formula <- as.formula(paste("Sepal.Length ~", x))
  gf_point(plot_formula, color = ~ Species, data = iris)
})
grid.arrange(grobs = plot_list)

错误原因

原代码中Sepal.Length ~ x里的x被当作独立变量而非iris数据集的列名,导致ggformula无法解析;显式指定data = iris则能确保Species在正确的数据源环境中被查找。

内容的提问来源于stack exchange,提问作者Ramakrishna S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:54:53