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

如何用purrr包的map函数批量生成多变量同类型可视化图?

问题分析与解决方案

你的代码存在的错误

  • 函数参数与内部变量不匹配:p1func的参数定义为df,但函数内部直接使用了purrr专属的占位符.x,该变量未在函数中定义,导致逻辑断裂。
  • map_at使用逻辑错误:map_at(df, c(2:4), ~p1func)是对数据集的第2-4列单独处理,此时传入p1func的是单个列向量,而非完整数据集,函数中需要的age_f列不存在于单个向量中,无法完成分组计算。
  • 函数调用未传参:~p1func没有将当前处理的列传递给函数,即使逻辑正确,也会因缺少必要参数报错。

正确实现方式

我们可以通过传递变量名给自定义函数,结合purrr::map批量生成图表,同时利用tidyeval语法处理变量引用。

方法1:字符串变量名 + tidyeval

# 定义通用绘图函数,接收数据集和目标变量名(字符串)
plot_rating <- function(df, var_name) {
  df %>%
    filter(!is.na(.data[[var_name]])) %>%  # 用.data[[var_name]]引用字符串变量
    group_by(age_f, .data[[var_name]]) %>%
    summarize(Count = n(), .groups = "drop") %>%  # 显式设置.groups避免分组警告
    mutate(pct = round(prop.table(Count)*100, 0), res = str_c(pct, "%")) %>%
    ggplot(aes(x = age_f, y = pct, fill = .data[[var_name]])) +
    geom_col(width = 0.6) +
    theme_bw() +
    theme(
      axis.title.x = element_blank(),
      axis.text.y = element_text(size = 25, face = "bold"),
      axis.title.y = element_blank(),
      legend.text = element_text(size = 25),
      legend.title = element_blank(),
      axis.line.y.left = element_line(color = 'gray'),
      panel.border = element_blank()
    ) +
    geom_text(aes(label = res), position = position_stack(vjust = .5), size = 10) +
    coord_flip() +
    scale_fill_brewer() +
    labs(title = str_c("Rating: ", var_name))  # 可选:添加标题区分不同图表
}

# 指定需要绘图的变量列表
vars_to_plot <- c("awareness_rating", "risk_rating", "like_rating")

# 批量生成图表,返回ggplot对象列表
plot_list <- map(vars_to_plot, ~plot_rating(df, .x))

# 查看单个图表,例如第二个
plot_list[[2]]

# 若需一次性展示所有图表,可使用patchwork包
# library(patchwork)
# wrap_plots(plot_list, ncol = 1)

方法2:转换为长格式数据(更贴合tidyverse思维)

先将宽格式数据集转为长格式,再按变量分组绘图:

# 转换为长格式
df_long <- df %>%
  pivot_longer(
    cols = c(awareness_rating, risk_rating, like_rating),
    names_to = "rating_type", 
    values_to = "rating_value"
  ) %>%
  filter(!is.na(rating_value))

# 按rating_type分组批量生成图表
plot_list <- df_long %>%
  group_split(rating_type) %>%
  map(function(sub_df) {
    sub_df %>%
      group_by(age_f, rating_value) %>%
      summarize(Count = n(), .groups = "drop") %>%
      mutate(pct = round(prop.table(Count)*100, 0), res = str_c(pct, "%")) %>%
      ggplot(aes(x = age_f, y = pct, fill = rating_value)) +
      geom_col(width = 0.6) +
      theme_bw() +
      theme(
        axis.title.x = element_blank(),
        axis.text.y = element_text(size = 25, face = "bold"),
        axis.title.y = element_blank(),
        legend.text = element_text(size = 25),
        legend.title = element_blank(),
        axis.line.y.left = element_line(color = 'gray'),
        panel.border = element_blank()
      ) +
      geom_text(aes(label = res), position = position_stack(vjust = .5), size = 10) +
      coord_flip() +
      scale_fill_brewer() +
      labs(title = unique(sub_df$rating_type))
  })

# 查看第三个图表
plot_list[[3]]

补充:批量保存图表

若需要将生成的图表批量保存到本地,可使用purrr::walk2配合ggsave:

walk2(plot_list, vars_to_plot, ~ggsave(
  filename = str_c(.y, ".png"), 
  plot = .x, 
  width = 10, 
  height = 8
))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:14:54