如何映射带多参数的绘图函数?ggplot2+purrr调用报错排查
批量调用绘图函数时提示"weightsgrp参数缺失"的解决方法
我有一个大型数据集,想要按医院绘制分出生体重组的多张图表。已经编写了myplott函数,单独调用(如myplott(actual_data, "hospital name", "weight group"))可正常生成图表,但使用purrr::map批量处理多个医院时,出现"argument 'weightsgrp' is missing, with no default"错误。
相关代码
绘图函数代码
myplott <- function(actual_data, hospital, weightsgrp) { print(paste0("Plot for hospital: ", hospital)) p <- ggplot(actual_data %>% filter(hosp_id == hospital , weight.group == weightsgrp), aes(x = format(date_discharge,"%b"), y = as.numeric(mortality), group = weightsgrp)) + facet_wrap(~weight.group) + geom_bar( stat = "identity") + theme_bw() + ylab("Percentage %") + ggtitle(hospital) + theme(axis.text.x = element_text(size = 13, hjust = 1, angle = 45)) + theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 20), legend.position = "top") + theme(legend.title = element_blank()) return(p) print(p) }
批量调用代码
plot_list <- unique(actual_data$hosp_id) %>% purrr::set_names() %>% purrr::map( ~ myplott(actual_data, .x))
错误信息
[1] "Plot for hospital: Bung Hospital" Error in `filter()`: ! Problem while computing `..2 = weight.group == weightsgrp`. i The error occurred in group 1: hosp_id = "Bung Hospital", weight.group = "1000 gms & Below". Caused by error: ! argument "weightsgrp" is missing, with no default
问题原因及解决方法
核心问题
你用map批量调用时,只给myplott传了两个参数(数据集和医院名称),但函数定义需要三个参数,第三个weightsgrp完全没传,所以触发了参数缺失的错误。
两种解决思路
思路1:给每个医院生成包含所有体重组的分面图
如果你的需求是每个医院一张图,用分面展示所有体重组,可以修改函数去掉weightsgrp参数,让函数自动筛选当前医院的所有体重组:
myplott <- function(actual_data, hospital) { print(paste0("Plot for hospital: ", hospital)) p <- ggplot(actual_data %>% filter(hosp_id == hospital), aes(x = format(date_discharge,"%b"), y = as.numeric(mortality), group = weight.group)) + facet_wrap(~weight.group) + geom_bar(stat = "identity") + theme_bw() + ylab("Percentage %") + ggtitle(hospital) + theme(axis.text.x = element_text(size = 13, hjust = 1, angle = 45)) + theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 20), legend.position = "top") + theme(legend.title = element_blank()) return(p) }
修改后原批量调用代码可以直接使用,每个医院会输出一张包含所有体重组的分面图表。
思路2:给每个医院的每个体重组单独生成图表
如果需要每个医院的每个体重组各生成一张独立图表,需要先生成医院和体重组的所有组合,再用pmap批量传递两个参数:
# 生成医院与体重组的所有组合 hosp_weight_combos <- expand.grid( hospital = unique(actual_data$hosp_id), weightsgrp = unique(actual_data$weight.group), stringsAsFactors = FALSE ) # 用pmap批量调用函数,传递组合中的两个参数 plot_list <- purrr::pmap(hosp_weight_combos, ~ myplott(actual_data, ..1, ..2)) # 可选:给图表列表命名,方便区分不同医院和体重组的图表 names(plot_list) <- paste(hosp_weight_combos$hospital, hosp_weight_combos$weightsgrp, sep = "_")
额外提示
原函数中return(p)之后的print(p)永远不会执行,因为return会直接终止函数运行,建议删掉这行无用代码。
内容的提问来源于stack exchange,提问作者LivingstoneM
相关产品推荐
相关产品推荐

