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

在purrr::map中调用as.ggplot时,如何规避全局变量赋值?

问题描述

我正在使用ggplotify包中的as.ggplot函数,包装circlize包生成的弦图,以便用patchwork包进行美观排版。但由于as.ggplot接受公式或表达式作为参数,似乎要求所有标识符都处于全局作用域中。我可以通过<<-将变量赋值到全局来解决,但这种方法显得不够规范。

我是在函数内部(通过purrr::map)调用as.ggplot的,因此内部的所有变量仅存在于局部作用域中,以下是简化示例:

失败示例:局部变量无法被识别

隐式变量.x仅存在于匿名map函数的作用域内,as.ggplot的公式无法找到它:

library(ggplotify)
library(purrr)
  
plots <- map(1:10,~{
  as.ggplot(~plot(seq(.x)))
})
#> Error in `map()`:
#> ℹ In index: 1.
#> Caused by error in `seq()`:
#> ! object '.x' not found
plots[[10]]
#> Error in eval(expr, envir, enclos): object 'plots' not found

成功但不规范的示例:使用全局变量

通过<<-将变量赋值到全局作用域,虽然能运行,但不符合编程规范:

library(ggplotify)
library(purrr)
  
plots <- map(1:10,~{
  x <<- .x
  as.ggplot(~plot(seq(x)))
})
plots[[10]]

示例生成的图

请问有没有无需使用<<-创建全局变量的解决方法?


解决方案

可以通过绑定公式的局部环境或利用rlang构造带环境的表达式,让as.ggplot能够访问到map匿名函数内的局部变量,以下是三种可靠方法:

方法1:手动为公式绑定当前局部环境

先构造公式,再将其环境设置为当前局部作用域,这样公式就能识别.x:

library(ggplotify)
library(purrr)

plots <- map(1:10, ~{
  p_formula <- ~plot(seq(.x))
  environment(p_formula) <- environment()
  as.ggplot(p_formula)
})

plots[[10]]

方法2:用rlang::new_formula直接创建带环境的公式

借助rlang包的new_formula函数,在创建公式时直接指定局部环境,一步完成:

library(ggplotify)
library(purrr)
library(rlang)

plots <- map(1:10, ~{
  as.ggplot(new_formula(NULL, expr(plot(seq(.x))), env = environment()))
})

plots[[10]]

方法3:使用as.ggplot的env参数(版本支持时)

如果你的ggplotify版本较新,as.ggplot提供了env参数,可直接传入局部环境,无需修改公式:

library(ggplotify)
library(purrr)

plots <- map(1:10, ~{
  as.ggplot(~plot(seq(.x)), env = environment())
})

plots[[10]]

以上方法均无需依赖全局变量,既符合编程规范,又能实现预期功能。


内容的提问来源于stack exchange,提问作者Luther Blissett

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:25:28