依赖dplyr的R自定义函数如何高效传入不同列作为参数
问题复现
示例数据框:
df <- data.frame(k = sample(1:2, 100, replace = TRUE), l = sample(1:2, 100, replace = TRUE), g = sample(1:3, 100, replace = TRUE, prob = c(0.2, 0.6, 0.2)))
自定义绘图函数:
library(tidyverse) fun_gg_factor <- function(p) { df %>% group_by(g) %>% count({{p}}) %>% mutate(Anteil = n / sum(n)) %>% ggplot(aes(x = {{p}}, y = Anteil)) + geom_col(position = position_dodge()) + facet_grid(.~g) }
手动调用函数可正常运行:
fun_gg_factor(k)
直接用sapply/循环传入c(k, l)会报错,提示k、l不是对象,无法批量为多列生成对应绘图。
解决方案
报错核心原因是dplyr的非标准评估语法无法直接适配基础循环/ sapply的传参逻辑,需要通过字符串转符号的方式传递列名,以下是两种可行实现:
方式1:列名字符串+符号转换批量生成独立图表
适合需要每个变量单独生成一张图的场景:
# 存储需要绘图的列名(字符串格式) plot_cols <- c("k", "l") # 批量生成图表,存储为列表 plot_list <- map(plot_cols, function(col) { fun_gg_factor(!!sym(col)) }) # 按需调用对应图表,比如查看变量k的绘图 plot_list[[1]] # 批量导出所有图片 walk2(plot_list, plot_cols, ~ggsave(paste0(.y, "_分组占比图.png"), .x, width = 8, height = 4))
方式2:长表转换一次性生成全变量汇总图
适合所有变量需要展示在同一张画布的场景,无需单独循环调用函数:
df %>% pivot_longer(cols = c(k, l), names_to = "变量", values_to = "取值") %>% group_by(g, 变量, 取值) %>% summarise(n = n(), .groups = "drop_last") %>% mutate(Anteil = n / sum(n)) %>% ggplot(aes(x = 取值, y = Anteil)) + geom_col(position = position_dodge()) + facet_grid(变量~g)
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

