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

在map()中使用ggplot2,如何在sec_axis()公式中引用对象?

在map()中为ggplot2的sec_axis()引用外部对象的解决方法

你遇到的问题其实是**作用域(scope)**的问题:sec_axis()里的公式默认会在ggplot的全局/顶层环境中查找变量,而map()迭代过程中的临时变量(比如你要引用的其他对象)并不在这个环境里,所以会出现“无法解析”的错误。下面给你几种实用的解决办法,结合你的示例代码来演示:

第一步:先构造完整的示例数据

首先我们把你的代码补全,同时添加一个需要在次Y轴中引用的对象(比如每年的n的均值mean_n):

library(tidyverse)
set.seed(1)

# 构造嵌套数据,并计算每个年份的n的均值
d <- tibble(
  n = sample(500:1000, 15),
  group = letters[rep(1:5, 3)],
  year = rep(2011:2013, each = 5)
) %>% 
  nest(data = -year) %>% 
  mutate(mean_n = map_dbl(data, ~mean(.$n)))

方法1:用准引用(!!)注入变量(最推荐)

使用!!(bang-bang操作符)把map()迭代中的变量直接注入到sec_axis()的公式里,这样公式就不需要去外部查找变量,而是直接使用变量的值:

# 生成带次Y轴的ggplot对象
d <- d %>% 
  mutate(gg1 = map2(data, mean_n, ~{
    ggplot(.x, aes(x = group, y = n)) +
      geom_col(fill = "#2c3e50") +
      scale_y_continuous(
        name = "原始n值",
        # 用!! .y把当前迭代的mean_n注入到公式中
        sec.axis = sec_axis(~ . / !! .y, name = "n / 年度均值")
      ) +
      labs(title = str_glue("年度:{.x$year[1]}"))
  }))

# 查看其中一张图
d$gg1[[1]]

方法2:传递自定义转换函数

如果你不习惯用准引用,也可以把次Y轴的转换逻辑写成一个普通函数,然后通过sec_axis()的args参数传递外部对象:

d <- d %>% 
  mutate(gg1 = map2(data, mean_n, ~{
    # 定义转换函数,接收y值和均值参数
    normalize_by_mean <- function(y, mean_val) {
      y / mean_val
    }
    
    ggplot(.x, aes(x = group, y = n)) +
      geom_col(fill = "#e74c3c") +
      scale_y_continuous(
        name = "原始n值",
        sec.axis = sec_axis(
          normalize_by_mean, 
          args = list(mean_val = .y), # 传递mean_n的值
          name = "n / 年度均值"
        )
      )
  }))

方法3:用local()创建本地环境

通过local()创建一个临时的本地环境,把需要引用的变量绑定到这个环境里,这样sec_axis()的公式就能找到它:

d <- d %>% 
  mutate(gg1 = map2(data, mean_n, ~{
    local({
      # 在本地环境中绑定mean_n的值
      current_mean <- .y
      ggplot(.x, aes(x = group, y = n)) +
        geom_col(fill = "#f39c12") +
        scale_y_continuous(
          name = "原始n值",
          sec.axis = sec_axis(~ . / current_mean, name = "n / 年度均值")
        )
    })
  }))

为什么会出现这个问题?

简单来说,sec_axis()的公式是延迟求值的——它不会在map()迭代的时候立即解析,而是等到ggplot渲染时才去查找变量。而map()里的临时变量(比如mean_n的每一个值)只存在于迭代的临时环境中,ggplot渲染时找不到这些变量,就会报错。上面的三种方法都是通过不同方式把变量的值“固定”到公式里,或者让公式能找到正确的环境。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:37:08