如何在ggplot2中使用for循环批量绘制独立箱线图?
解决ggplot循环绘制箱线图的空图与报错问题
问题场景
尝试用for循环为mtcars数据集的多列(mpg、cyl、disp)绘制独立的小提琴图+箱线图时,循环内代码返回空图;尝试用noquote()处理变量名后又触发报错Error: Discrete value supplied to continuous scale,但单独运行某一列的代码能正常生成图表。
原空图代码
# 选择列 num_vars_example = c('mpg', 'cyl', 'disp') for (i in num_vars_example) { print( ggplot(data = mtcars, aes(x = factor(0), i)) + geom_violin() + geom_boxplot(width=0.3, color="blue", alpha=0.2) + theme(axis.title.x=element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank()) ) }
报错代码及信息
for (i in num_vars_example) { print( ggplot(data = mtcars, aes(x = factor(0), noquote(i))) + geom_violin() + geom_boxplot(width=0.3, color="blue", alpha=0.2) + theme(axis.title.x=element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank()) ) }
Error: Discrete value supplied to continuous scale
正常运行的单列代码
ggplot(data = mtcars, aes(x = factor(0), mpg)) + # 绘制mpg列 geom_violin() + geom_boxplot(width=0.3, color="blue", alpha=0.2) + theme(axis.title.x=element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank())
问题原因
ggplot的aes()默认使用非标准求值,直接传入字符串变量i时,它不会解析为数据框的列名,而是将i作为字面量处理,导致没有对应数据生成空图;而noquote()仅去除字符串的引号标记,本质仍是字符串,ggplot会将其识别为离散值,与x轴的factor(0)类型不匹配,因此触发报错。
修正方案
方案1:使用.data代词(推荐)
利用ggplot内置的.data代词,明确指定从数据框中引用名为i的列,代码简洁且符合现代ggplot规范:
library(ggplot2) num_vars_example = c('mpg', 'cyl', 'disp') for (i in num_vars_example) { print( ggplot(data = mtcars, aes(x = factor(0), y = .data[[i]])) + geom_violin() + geom_boxplot(width=0.3, color="blue", alpha=0.2) + labs(y = i) + # 为y轴添加对应变量名标题 theme(axis.title.x=element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank()) ) }
方案2:使用aes_string()(兼容旧版ggplot)
若使用的是较旧版本的ggplot,可使用aes_string()接受字符串形式的参数:
library(ggplot2) num_vars_example = c('mpg', 'cyl', 'disp') for (i in num_vars_example) { print( ggplot(data = mtcars, aes_string(x = "factor(0)", y = i)) + geom_violin() + geom_boxplot(width=0.3, color="blue", alpha=0.2) + labs(y = i) + theme(axis.title.x=element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank()) ) }
注意:aes_string()内的所有参数都需要写成字符串形式,比如x = "factor(0)"。
内容的提问来源于stack exchange,提问作者Rods2292
相关产品推荐
相关产品推荐

