ggplot2调用geom_text添加筛选行名标签时触发数据长度报错
报错原因
- 包名拼写错误:加载语句中
tidyerse为错误拼写,正确包名为tidyverse,缺写字母v会导致包加载失败。 - 核心长度不匹配问题:你给
geom_text_repel单独传入了filter(x>10)筛选后的子数据集(示例中筛选后为14行),但aes内的label映射写的是rownames(df),调用的是原始完整df的30个行名,长度和当前图层使用的子数据集行数不一致,触发ggplot的美学映射长度校验报错。 - 补充:第一段全量标注的代码虽然能运行,但直接在
aes里硬索引全局环境的原始df属于不规范写法,一旦数据做筛选、排序操作,就很容易出现标签和点错位、长度不匹配的问题。
修复方法
最稳妥的方案是提前把行名存为数据框的固定列,后续所有图层直接映射该列即可,不需要反复调用原始数据框的行名,从根源避免长度不匹配、索引错位问题。
修复后可正常运行的完整代码:
require("ggrepel") require("tidyverse") # 修正包名拼写 x <- sample(x = 1:20, size = 30, replace = T) y <- sample(x = 1:20, size = 30, replace = T) df <- data.frame(x,y) # 提前将行名存入数据框作为独立列 df$row_label <- rownames(df) # 全量数据标注 df %>% ggplot(aes(x=x,y=y))+ geom_point()+ geom_text_repel(aes(label = row_label)) # 筛选x>10的点标注,无报错 df %>% ggplot(aes(x=x,y=y))+ geom_point()+ geom_text_repel(data = . %>% filter(x>10), aes(label = row_label))
如果不想提前新增列,也可以在传入geom_text_repel的数据集里动态计算行名,但写法不如提前存列直观,容易出错:
df %>% ggplot(aes(x=x,y=y))+ geom_point()+ geom_text_repel(data = . %>% filter(x>10) %>% mutate(label = rownames(.)), aes(label = label))
内容的提问来源于stack exchange,提问作者rez
相关产品推荐
相关产品推荐

