gghighlight报错:无法找到自身创建的列,添加geom_hline后异常
问题:使用gghighlight时添加geom_hline报错
数据与初始代码
先定义数据框:
library(tidyverse) library(gghighlight) # 可正常运行的数据定义 df <- tibble::tribble( ~year, ~sales_rep, ~sale_count, 2021, "1", 615, 2021, "2", 246, 2021, "3", 245, 2022, "1", 736, 2022, "2", 56, 2022, "3", 868, 2023, "1", 452, 2023, "2", 185, 2023, "3", 915 )
想要绘制每位销售代表的销售额,并通过gghighlight突出销售代表1,以下代码可正常运行:
df %>% ggplot( aes( x = year, y = sale_count, fill = sales_rep ) ) + geom_col() + facet_wrap( vars(sales_rep) ) + gghighlight(sales_rep == 1, calculate_per_facet = TRUE) #> Warning: Tried to calculate with group_by(), but the calculation failed. #> Falling back to ungrouped filter operation...

报错场景
当添加geom_hline来显示每位销售代表的年度平均销售额时,代码抛出错误:
# 运行失败的代码 avg_by_rep <- df %>% summarize( avg_sales = mean(sale_count), .by = sales_rep ) df %>% ggplot( aes( x = year, y = sale_count, fill = sales_rep ) ) + geom_col() + geom_hline( data = avg_by_rep, aes( yintercept = avg_sales ) ) + facet_wrap( vars(sales_rep) ) + gghighlight(sales_rep == 1, calculate_per_facet = TRUE) #> New names: #> * `highlight..........1` -> `highlight.......` #> Warning: Tried to calculate with group_by(), but the calculation failed. #> Falling back to ungrouped filter operation... #> Error in `geom_hline()`: #> ! Problem while computing aesthetics. #> i Error occurred in the 2nd layer. #> Caused by error in `FUN()`: #> ! object 'highlight..........1' not found #> Backtrace: #> x #> 1. +-base::tryCatch(...) #> 2. | \-base (local) tryCatchList(expr, classes, parentenv, handlers) #> 3. | +-base (local) tryCatchOne(...) #> 4. | | \-base (local) doTryCatch(return(expr), name, parentenv, handler) #> 5. | \-base (local) tryCatchList(expr, names[-nh], parentenv, handlers[-nh]) #> 6. | \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 7. | \-base (local) doTryCatch(return(expr), name, parentenv, handler) #> 8. +-base::withCallingHandlers(...) #> 9. +-base::saveRDS(...) #> 10. +-base::do.call(...) #> 11. +-base (local) `<fn>`(...) #> 12. +-global `<fn>`(input = base::quote("large-unau_reprex.R")) #> 13. | \-rmarkdown::render(input, quiet = TRUE, envir = globalenv(), encoding = "UTF-8") #> 14. | \-knitr::knit(knit_input, knit_output, envir = envir, quiet = quiet) #> 15. | \-knitr:::process_file(text, output) #> 16. | +-base::withCallingHandlers(...) #> 17. | +-knitr:::process_group(group) #> 18. | \-knitr:::process_group.block(group) #> 19. | \-knitr:::call_block(x) #> 20. | \-knitr:::block_exec(params) #> 21. | \-knitr:::eng_r(options) #> 22. | +-knitr:::in_input_dir(...) #> 23. | | \-knitr:::in_dir(input_dir(), expr) #> 24. | \-knitr (local) evaluate(...) #> 25. | \-evaluate::evaluate(...) #> 26. | \-evaluate:::evaluate_call(...) #> 27. | +-evaluate (local) handle(...) #> 28. | | \-base::try(f, silent = TRUE) #> 29. | | \-base::tryCatch(...) #> 30. | | \-base (local) tryCatchList(expr, classes, parentenv, handlers) #> 31. | | \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 32. | | \-base (local) doTryCatch(return(expr), name, parentenv, handler) #> 33. | +-base::withCallingHandlers(...) #> 34. | +-base::withVisible(value_fun(ev$value, ev$visible)) #> 35. | \-knitr (local) value_fun(ev$value, ev$visible) #> 36. | \-knitr (local) fun(x, options = options) #> 37. | +-base::withVisible(knit_print(x, ...)) #> 38. | +-knitr::knit_print(x, ...) #> 39. | \-knitr:::knit_print.default(x, ...) #> 40. | \-evaluate (local) normal_print(x) #> 41. | +-base::print(x) #> 42. | \-ggplot2:::print.ggplot(x) #> 43. | +-ggplot2::ggplot_build(x) #> 44. | \-ggplot2:::ggplot_build.ggplot(x) #> 45. | \-ggplot2:::by_layer(...) #> 46. | +-rlang::try_fetch(...) #> 47. | | +-base::tryCatch(...) #> 48. | | | \-base (local) tryCatchList(expr, classes, parentenv, handlers) #> 49. | | | \-base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 50. | | | \-base (local) doTryCatch(return(expr), name, parentenv, handler) #> 51. | | \-base::withCallingHandlers(...) #> 52. | \-ggplot2 (local) f(l = layers[[i]], d = data[[i]]) #> 53. | \-l$compute_aesthetics(d, plot) #> 54. | \-ggplot2 (local) compute_aesthetics(..., self = self) #> 55. | \-base::lapply(aesthetics, eval_tidy, data = data, env = env) #> 56. | \-rlang (local) FUN(X[[i]], ...) #> 57. \-base::.handleSimpleError(...) #> 58. \-rlang (local) h(simpleError(msg, call)) #> 59. \-handlers[[1L]](cnd) #> 60. \-cli::cli_abort(...) #> 61. \-rlang::abort(...)
解决方案
报错原因是gghighlight会处理所有图层的数据,但avg_by_rep中没有gghighlight生成的标记列,导致匹配失败。可以用以下两种方法解决:
方法1:给geom_hline添加inherit.aes = FALSE
禁用该图层对全局美学映射的继承,避免gghighlight处理此图层的数据:
avg_by_rep <- df %>% summarize( avg_sales = mean(sale_count), .by = sales_rep ) df %>% ggplot( aes( x = year, y = sale_count, fill = sales_rep ) ) + geom_col() + geom_hline( data = avg_by_rep, aes(yintercept = avg_sales), inherit.aes = FALSE # 禁用全局美学继承 ) + facet_wrap(vars(sales_rep)) + gghighlight(sales_rep == 1, calculate_per_facet = TRUE)
方法2:将平均数据合并到主数据框
把每位销售代表的平均销售额添加到主数据框,让gghighlight处理时数据结构一致:
df_with_avg <- df %>% group_by(sales_rep) %>% mutate(avg_sales = mean(sale_count)) %>% ungroup() df_with_avg %>% ggplot( aes( x = year, y = sale_count, fill = sales_rep ) ) + geom_col() + geom_hline(aes(yintercept = avg_sales)) + facet_wrap(vars(sales_rep)) + gghighlight(sales_rep == 1, calculate_per_facet = TRUE)
内容的提问来源于stack exchange,提问作者joshbrows
相关产品推荐
相关产品推荐

