如何用lapply绘制数值变量与分类变量组合的箱线图?
批量生成数值-分类变量组合箱线图的解决方案
问题背景
你有包含数值和分类变量的数据集,希望生成所有数值变量(y轴)与分类变量(填充分组)组合的箱线图,但直接用lapply(num, boxplot_num_x_cat,cat)报错,原因是传入了整个分类变量向量而非单个元素。
修正步骤与代码
1. 准备数据与变量区分
先加载tidyverse工具包,修正变量命名(避免和R内置函数cat冲突):
library(tidyverse) # 示例数据集 data <- data.frame(numA= c(50, 47, 49, 47, 46, 48, 45), numB= c(625, 546, 590, 690, 641, 526, 600), numC=c(38.246, 26.025, 23.999, 62.294, 12.149, 23.738, 68.664), catA = c("A","A","A","B","B","C","C"), catB = c("dd","ee","ff","dd","ee","ff","dd")) # 区分数值和分类变量 is_numeric <- unlist(lapply(data, is.numeric), use.names = TRUE) cat_vars <- colnames(data[, !is_numeric]) num_vars <- colnames(data[, is_numeric])
2. 生成所有变量组合
用expand.grid创建数值变量与分类变量的所有两两组合:
# 生成所有需要绘制的变量组合 plot_pairs <- expand.grid(num = num_vars, cat = cat_vars, stringsAsFactors = FALSE)
3. 修正绘图函数
使用tidyverse的.data代词引用列名,让函数更规范且支持动态变量名:
boxplot_num_x_cat <- function(num_col, cat_col, df) { ggplot(df, aes(y = .data[[num_col]], fill = .data[[cat_col]])) + geom_boxplot() + labs(y = num_col, x = cat_col, fill = cat_col, title = str_glue("箱线图:{num_col} 按 {cat_col} 分组")) }
4. 批量生成并存储图表
用purrr::pmap遍历所有组合,将生成的箱线图存储到列表中:
# 批量生成所有组合的箱线图,结果存入列表 plot_list <- pmap(plot_pairs, boxplot_num_x_cat, df = data)
额外操作
- 查看单张图:用
plot_list[[1]]、plot_list[[2]]等索引调用 - 批量保存图表:
# 生成文件名并批量保存 plot_filenames <- str_c(plot_pairs$num, "_vs_", plot_pairs$cat, ".png") walk2(plot_list, plot_filenames, ~ggsave(.y, .x, width = 6, height = 4))
错误原因说明
原来的lapply(num, boxplot_num_x_cat,cat)会把整个cat向量(如c("catA","catB"))作为第二个参数传入函数,但函数期望的是单个分类变量名,导致ggplot无法识别分组列,因此报错。生成两两组合后遍历每一对,就能确保每次传入单个变量名。
内容的提问来源于stack exchange,提问作者Appo_55
相关产品推荐
相关产品推荐

