R ggplot2:如何在分面散点图中为指定无关联点绘制连接线
解决方法
你之前添加geom_line(aes(x = stat, group=group))不符合预期的核心原因是:你设置的分组变量对应诊断等级,会跨多个test分面,ggplot会默认跨分面连接数据,同时会将三个stat的点全部串联,不符合你仅需要从患病率分别连接两个后验概率的需求。
正确实现方式为单独构造连接线专用的辅助数据集,仅保留需要连接的点对,再传入geom_line即可,完整可运行代码如下:
# 先加载需要的包 library(tidyverse) # 载入你提供的数据集 probpostest <- structure(list(prev = c(15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5), group = c("proven", "proven", "proven", "proven_likely", "proven_likely", "proven_likely", "proven_likely_possible", "proven_likely_possible", "proven_likely_possible", "proven", "proven", "proven", "proven_likely", "proven_likely", "proven_likely", "proven_likely_possible", "proven_likely_possible", "proven_likely_possible", "proven", "proven", "proven", "proven_likely", "proven_likely", "proven_likely", "proven_likely_possible", "proven_likely_possible", "proven_likely_possible", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven", "proven" ), test = c("T2Candida", "T2Candida", "T2Candida", "T2Candida", "T2Candida", "T2Candida", "T2Candida", "T2Candida", "T2Candida", "Hemocultivo", "Hemocultivo", "Hemocultivo", "Hemocultivo", "Hemocultivo", "Hemocultivo", "Hemocultivo", "Hemocultivo", "Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida", "T2Candida", "T2Candida", "Hemocultivo", "Hemocultivo", "Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida", "T2Candida", "T2Candida", "Hemocultivo", "Hemocultivo", "Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo", "T2Candida + Hemocultivo"), stat = c("prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo", "prevalencia", "probpostestpositivo", "probpostestnegativo"), estimator = c(0.158, 0.635718612096565, 0.0361721611721612, 0.404, 0.637998056365403, 0.351610095735422, 0.561, 0.908822796377835, 0.472165444270771, 0.158, 1, 0.101195559350982, 0.404, 1, 0.351610095735422, 0.561, 1, 0.534908358936328, 0.158, NA, 0.0184192119375146, 0.404, NA, 0.321802457897132, 0.561, NA, 0.472165444270771, 0.1, 0.508196721311476, 0.0217391304347826, 0.1, 1, 0.0625, 0.1, NA, 0.010989010989011, 0.05, 0.328621908127209, 0.0104166666666667, 0.05, 1, 0.0306122448979592, 0.05, NA, 0.00523560209424084 ), lower = c("7.5", NA, NA, "27.6", NA, NA, "42.4", NA, NA, "7.5", NA, NA, "27.6", NA, NA, "42.4", NA, NA, "7.5", NA, NA, "27.6", NA, NA, "42.4", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), upper = c("27.9", NA, NA, "54.2", NA, NA, "69.3", NA, NA, "27.9", NA, NA, "54.2", NA, NA, "69.3", NA, NA, "27.9", NA, NA, "54.2", NA, NA, "69.3", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA )), row.names = c(NA, -45L), class = c("tbl_df", "tbl", "data.frame" )) # 处理主绘图数据 plot_data <- probpostest %>% filter(prev==15) %>% mutate( stat=replace(stat,stat=="prevalencia","Prevalencia"), stat=replace(stat,stat=="probpostestpositivo","Probabilidad\nPostest\nPositivo"), stat=replace(stat,stat=="probpostestnegativo","Probabilidad\nPostest\nNegativo"), group=replace(group,group=="proven","Confirmada"), group=replace(group,group=="proven_likely","Confirmada o\nprobable"), group=replace(group,group=="proven_likely_possible","Confirmada,\nprobable o\nposible"), # 提前计算y值,方便后续构造连接线数据 y_val = if_else(is.na(estimator*100), 100, estimator*100) ) %>% mutate(across(stat, factor, levels=c("Prevalencia","Probabilidad\nPostest\nPositivo","Probabilidad\nPostest\nNegativo")), across(c(lower,upper), as.numeric), lower=lower/100, upper=upper/100) # 构造连接线辅助数据:每个分面内仅保留 患病率→阳性后验、患病率→阴性后验 两组连线 line_data <- plot_data %>% # 过滤掉estimator为NA的点,不需要连接NC标签的位置 filter(!is.na(estimator)) %>% group_by(group, test) %>% # 每组生成两条连线 reframe( line1 = list(tibble( stat = c("Prevalencia", "Probabilidad\nPostest\nPositivo"), y_val = c(y_val[stat=="Prevalencia"], y_val[stat=="Probabilidad\nPostest\nPositivo"]) )), line2 = list(tibble( stat = c("Prevalencia", "Probabilidad\nPostest\nNegativo"), y_val = c(y_val[stat=="Prevalencia"], y_val[stat=="Probabilidad\nPostest\nNegativo"]) )) ) %>% unnest(cols = c(line1, line2), names_sep = "_") %>% # 整理成长格式,给每条连线分配唯一id pivot_longer(cols = -c(group, test), names_to = c("line_id", ".value"), names_sep = "_") %>% filter(!is.na(y_val)) # 绘图 ggplot(plot_data, aes(x=stat, y=y_val, ymin=lower, ymax=upper, color=stat)) + # 先加连接线,放在点图层下方避免遮挡 geom_line(data = line_data, aes(x = stat, y = y_val, group = line_id), color = "gray50", linewidth = 0.8, inherit.aes = FALSE) + geom_point(size = 2) + geom_text(aes(label=if_else(is.na(estimator), "NC", paste0(sprintf("%2.2f",estimator*100),"%")), vjust=if_else(is.infinite(estimator), 1, 0.5), hjust=-0.25), show.legend = FALSE, size=4) + labs(x=NULL,y=NULL,title = "Figura 5. Probabilidades pre-test y post-test.", caption="Prevalencia: probabilidad pre-test.\n\nProbabilidad pos-test positivo y negativo: probabilidad de tener candidiasis invasiva después de obtener un resultado positivo o negativo, respectivamente.\n\nNC: no calculable.")+ facet_grid(group ~ test, scales = "free_y", switch = "y" ) + theme_minimal()+ theme(plot.title = element_text(hjust = 0.5), plot.caption = element_text(hjust = 0), legend.position = "none", strip.text = element_text(face="bold")) + scale_y_continuous(position = "right") + scale_color_brewer(palette = "Set1")
如果需要调整连接线的颜色、粗细,直接修改geom_line里的color、linewidth参数即可。
内容的提问来源于stack exchange,提问作者jajb
相关产品推荐
相关产品推荐

