R语言ggplot2中如何向facet_grid()传入任意数量分面变量
问题原因
两个自定义函数运行失败的核心原因是:facet_grid()配套的vars()函数接收的是数据掩码下的变量引用/未计算表达式,你直接传入字符串向量、或是未做类型转换就用!!!拼接时,无法被识别为数据集内的有效列,所以报错。
可行解决方案
下面提供两种适配不同传参习惯的正确写法,都可以支持任意数量的分面变量传入:
方案1:命名参数接收字符串向量
你之前直接用!!!factor.by拼接失效,是因为传入的是普通字符串向量,需要先用rlang::syms()把每个字符串转换成R语言的符号对象,再做反引用拼接即可:
library(ggplot2) library(rlang) make_graph <- function (factor.by){ facet_vars <- syms(factor.by) ggplot(mpg, aes(cyl, cty)) + geom_col() + facet_grid(cols = vars(!!!facet_vars)) } # 调用示例 make_graph(factor.by = c("manufacturer", "model"))
方案2:...参数接收任意数量分面变量
如果不想固定参数名,用...接收分面变量时,先用rlang::enquos()捕获所有传入的表达式,再拼接到vars()中即可,这种写法同时支持传入裸列名、字符串两种形式,灵活性更高:
make_graph_2 <- function (...){ facet_args <- enquos(...) ggplot(mpg, aes(cyl, cty)) + geom_col() + facet_grid(cols = vars(!!!facet_args)) } # 两种调用方式均可正常运行 # 传裸列名 make_graph_2(manufacturer, model) # 传字符串 make_graph_2("manufacturer", "model")
注意事项
- 你之前测试第二个函数时把
manufacturer拼写成了manufactuer(漏了末尾的字母r),即便代码逻辑正确也会触发“找不到列”的报错,调试时要注意核对列名拼写 - 如果需要同时支持行、列两个方向的分面,只要把对应捕获的符号列表传给
facet_grid()的rows参数即可,逻辑和列分面完全一致 - 处理ggplot2自定义函数的传参问题时不用死记硬背准引用规则:传入字符串向量时先用
rlang::syms()转成符号列表,传入裸列名时先用rlang::enquos()捕获表达式,最后都用!!!拼接到对应参数位置即可,这套逻辑能覆盖绝大多数绘图自定义函数的开发场景。
内容的提问来源于stack exchange,提问作者e720
相关产品推荐
相关产品推荐

