R ggplot2使用jitter时如何将关联的收入支出数据点成对绑定?
解决方案
你的需求核心是同ID对应的收入、支出点使用完全相同的抖动偏移量,避免二者错位,以下是两种可直接运行的实现方案:
方案1:内置position参数实现(代码最简)
直接利用ggplot2的position_jitterdodge,将ID设为分组变量,设置躲避宽度为0,即可保证同组(同ID)的两点不会错开,仅整体做抖动偏移:
library(ggplot2) ccode <- c(Gain="darkseagreen", Spend="darkblue") ef<-data.frame( date=as.Date(c("2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-01","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-02","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03","2021-03-03")), site=c("Castle","Temple","Temple","Temple","Temple","Temple","Palace","Palace","Castle","Castle","Castle","Temple","Temple","Palace","Palace","Castle","Castle","Castle","Castle","Castle","Temple","Temple","Palace","Castle","Temple","Temple","Temple","Temple","Temple","Palace","Palace","Castle","Castle","Castle","Temple","Temple","Palace","Palace","Castle","Castle","Castle","Castle","Castle","Temple","Temple","Palace"), id=c("C123","T101","T93","T94","T95","T96","P102","P96","C126","C127","C128","T100","T98","P100","P98","C129","C130","C131","C132","C133","T104","T99","P99","C123","T101","T93","T94","T95","T96","P102","P96","C126","C127","C128","T100","T98","P100","P98","C129","C130","C131","C132","C133","T104","T99","P99"), gainspend=c("Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Gain","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend","Spend"), amount=c(6,14,34,31,3,10,6,14,2,16,16,14,1,1,15,11,8,7,2,10,15,4,3,NA,NA,4,5,NA,NA,NA,NA,NA,NA,2,NA,1,NA,3,NA,NA,2,NA,NA,2,NA,3)) ggplot(ef, aes(date, site, group = id)) + geom_point(aes(size = amount, color = gainspend), alpha = 0.5, position = position_jitterdodge(jitter.width = 0, jitter.height = 0.2, dodge.width = 0)) + scale_color_manual(values = ccode) + scale_size_continuous(range = c(1,15), breaks = c(5,10,20))
方案2:手动生成固定偏移量(可控性最高)
如果需要自定义偏移规则,可以提前给每个唯一ID分配固定的垂直偏移值,同ID的收入、支出点共用同一个偏移量,天然对齐:
library(ggplot2) library(dplyr) ccode <- c(Gain="darkseagreen", Spend="darkblue") # 固定随机种子保证结果可复现 set.seed(123) # 给每个ID生成唯一的垂直偏移量,范围和原jitter参数匹配 id_offset <- distinct(ef, id) %>% mutate(y_offset = runif(n(), min = -0.2, max = 0.2)) # 合并偏移量到原数据集 ef <- left_join(ef, id_offset, by = "id") ggplot(ef, aes(x = date, y = as.numeric(factor(site)) + y_offset)) + geom_point(aes(size = amount, color = gainspend), alpha = 0.5) + # 还原y轴标签为站点名称 scale_y_continuous(breaks = 1:nlevels(factor(ef$site)), labels = levels(factor(ef$site)), name = "site") + scale_color_manual(values = ccode) + scale_size_continuous(range = c(1,15), breaks = c(5,10,20))
两种方案均可以实现预期效果:同ID对应的绿色收入点和蓝色支出点完全中心对齐,同时整体添加抖动避免不同ID的点重叠。
内容的提问来源于stack exchange,提问作者schumacher
相关产品推荐
相关产品推荐

