You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 22:10:31