R语言中使用整洁评估时ggplot2 facet_wrap标签的问题
问题:动态设置ggplot分面标签(包含聚合计算结果)
需要编写可适配不同数据集的函数,根据传入的列参数进行分面,且分面标签需包含对应分组下percBackground列的总和。尝试使用rlang的{{}}语法但未成功,运行代码时报错。
测试数据与原代码
data.test <- data.frame(broad = c("A", "A", "A", "B", "B", "C", "C", "C", "C"), detail = c("a", "b", "c", "d", "e", "f", "g", "h", "i"), sr.Summer = c(12, 23, 32, 12, 12, 11, 14, 15, 18), percBackground = c(1.5, 4.3, 3.4, 4.6, 3.4, 4.1, 3.9, 2.9, 1.8)) func.test <- function(data, facet.by){ aggr <- data %>% aggregate(percBackground ~ facet.by, FUN = sum) %>% mutate(label = paste0(facet.by, " - ", round(percBackground, digits = 2), "%")) facet_label <- aggr$label names(facet_label) <- unique(facet_label) ggplot(data = data, aes(x = detail)) + geom_point(aes(y = sr.Summer)) + facet_wrap(~facet.by, labeller = labeller(facet.by = facet_label)) } func.test(data = data.test, facet.by = broad)
报错信息
> Error in eval(predvars, data, env) : object 'broad' not found 13. eval(predvars, data, env) 12. eval(predvars, data, env) 11. model.frame.default(formula = by, data = x) 10. stats::model.frame(formula = by, data = x) 9. eval(m, parent.frame()) 8. eval(m, parent.frame()) 7. aggregate.formula(x = by, data = x, FUN = FUN, ...) 6. aggregate.data.frame(., percBackground ~ facet.by, FUN = sum) 5. aggregate(., percBackground ~ facet.by, FUN = sum) 4. aggregate(., percBackground ~ facet.by, FUN = sum) 3. mutate(., label = paste0(facet.by, " - ", round(percBackground, digits = 2), "%")) 2. data %>% aggregate(percBackground ~ facet.by, FUN = sum) %>% mutate(label = paste0(facet.by, " - ", round(percBackground, digits = 2), "%")) 1. func.test(data.test, broad)
解决方案
错误根源是未正确处理非标准求值(NSE),即函数参数中的列名未被正确解析。以下是修改后的代码及关键要点:
修改后的完整代码
library(tidyverse) data.test <- data.frame(broad = c("A", "A", "A", "B", "B", "C", "C", "C", "C"), detail = c("a", "b", "c", "d", "e", "f", "g", "h", "i"), sr.Summer = c(12, 23, 32, 12, 12, 11, 14, 15, 18), percBackground = c(1.5, 4.3, 3.4, 4.6, 3.4, 4.1, 3.9, 2.9, 1.8)) func.test <- function(data, facet.by){ # 计算分组总和并生成自定义标签 aggr <- data %>% group_by({{facet.by}}) %>% summarize(total_perc = sum(percBackground), .groups = "drop") %>% mutate(label = paste0({{facet.by}}, " - ", round(total_perc, 2), "%")) # 构建标签映射:原始分组值 -> 带总和的标签 facet_label <- set_names(aggr$label, aggr %>% pull({{facet.by}})) # 绘图,用{{}}传递动态列参数 ggplot(data, aes(x = detail)) + geom_point(aes(y = sr.Summer)) + facet_wrap(vars({{facet.by}}), labeller = labeller(facet.by = facet_label)) } # 调用函数 func.test(data = data.test, facet.by = broad)
关键修改说明
{{}}语法的正确使用:在group_by()、pull()、vars()中用{{facet.by}}引用动态列参数,让R正确识别数据框中的目标列。- 替换聚合方式:用
group_by()+summarize()替代aggregate,更适配非标准求值场景,代码可读性更高。 - 正确构建标签映射:用
set_names()创建键值对,键为分组的原始值(如"A"、"B"),值为自定义标签,确保labeller能精准匹配替换。 - ggplot分面语法适配:用
vars({{facet.by}})替代~facet.by,符合ggplot的非标准求值语法要求。
内容的提问来源于stack exchange,提问作者apple
相关产品推荐
相关产品推荐

