如何修改ggplot2对象中的quosure,仅显示占比超5%的标签?
问题描述
我用likert包创建了一个ggplot2对象,已经通过以下代码修改了标签的字体样式和字体族:
p$layers[[2]]$aes_params$fontface = "bold" p$layers[[2]]$aes_params$fontfamily = "Calibri"
需要修改的标签对应:
p$layers[[2]]$mapping$label
想修改这个quosure,让标签仅显示占比大于5%的值。
可复现代码:
options(digits=2) require(likert) data(pisaitems) ##### Item 24: Reading Attitudes items24 <- pisaitems[,substr(names(pisaitems), 1,5) == 'ST24Q'] head(items24); ncol(items24) names(items24) <- c( ST24Q01="I read only if I have to.", ST24Q02="Reading is one of my favorite hobbies.", ST24Q03="I like talking about books with other people.", ST24Q04="I find it hard to finish books.", ST24Q05="I feel happy if I receive a book as a present.", ST24Q06="For me, reading is a waste of time.", ST24Q07="I enjoy going to a bookstore or a library.", ST24Q08="I read only to get information that I need.", ST24Q09="I cannot sit still and read for more than a few minutes.", ST24Q10="I like to express my opinions about books I have read.", ST24Q11="I like to exchange books with my friends.") str(items24) l24 <- likert(items24) lr <- plot(l24, # Group the items alphabetically #group.order= group_names, # for sorting ascending negative answers # Plot the percentages for each response category plot.percents = TRUE, # Plot the total percentage for negative responses plot.percent.low = FALSE, # Plot the total percentage for positive responses plot.percent.high = FALSE, # Whether response categories should be centered # This is only helpful when there is a middle response # option such as "neutral" or "neither agree nor disagree" centered = FALSE, # change the legend position legend.position = 'bottom', # Wrap label text for item labels wrap=200, text.size = 6, text.color = 'white') lr$layers[[2]]$mapping$label
我尝试了以下代码但报错:
lr$layers[[2]]$mapping$label <- quo(rlang::as_quosure("ifelse(round(value) < 5, '', paste0(round(value), \"%\")", env = rlang::caller_env())) lr$layers[[2]]$mapping$label <- quo(rlang::as_quosure("ifelse(round(value) < 5, '', paste0(round(value), \"%\")"), env = 0x000001eab3634ea0)
报错信息:
Don't know how to automatically pick scale for object of type <quosure/formula>. Defaulting to continuous. Error in `geom_text()`: ! Problem while computing aesthetics. i Error occurred in the 2nd layer. Caused by error in `compute_aesthetics()`: ! Aesthetics are not valid data columns. x The following aesthetics are invalid: x `label = rlang::as_quosure(...)` i Did you mistype the name of a data column or forget to add `after_stat()`?
解决方法
你之前的错误在于嵌套了quosure构造函数,直接把as_quosure放在quo()里会让ggplot无法正确解析美学映射。正确的做法是直接构造包含条件逻辑的quosure,替换原有的label映射:
# 替换第二层的label映射 lr$layers[[2]]$mapping$label <- quo(ifelse(round(value) >= 5, paste0(round(value), "%"), ""))
说明
- 原标签基于数据中的
value字段(百分比数值)生成,我们直接在quosure里用ifelse判断:当round(value)大于等于5时,显示带百分号的数值;否则显示空字符串(即隐藏标签)。 - 无需额外嵌套
as_quosure,quo()已经能生成正确的引用对象,ggplot可直接解析该逻辑。
修改后直接打印lr即可看到效果:占比小于5%的标签会被隐藏,仅显示占比≥5%的标签。
内容的提问来源于stack exchange,提问作者bookerbn
相关产品推荐
相关产品推荐

