R语言径向图标签连接优化:避免标签重叠的解决方案求助
问题
作为R语言新手,绘制带不同大小、颜色数据点的径向图时遇到标签重叠问题。尝试用线段连接标签和数据点,但线段仅水平/垂直,标签位置不准,效果差。优先用base R解决,也接受其他方案。
数据(前6行)
study year c p mc mp sc sp yi vi 1 1 2015 54 6 68.130 26.500 34.861 24.450 1.2053 0.1973 2 2 2007 26 8 23.000 18.400 13.000 8.200 0.3708 0.1655 3 3 2023 78 9 60.010 48.670 25.480 31.220 0.4311 0.1250 4 4 2013 69 9 53.400 24.700 37.700 25.700 0.7759 0.1295 5 5 2008 4 1 17.500 1.200 12.010 1.000 0.9821 1.3464 6 6 2015 40 8 132.075 25.875 38.697 23.648 2.8381 0.2339
c/p:两组样本量mc/mp:两组均值sc/sp:两组标准差yi/vi:效应量及方差
数据结构
Classes ‘escalc’ and 'data.frame': 18 obs. of 10 variables: $ study: num 1 2 3 4 5 6 7 8 9 10 ... $ year : num 2015 2007 2023 2013 2008 ... $ c : num 54 26 78 69 4 40 38 88 7 24 ... $ p : num 6 8 9 9 1 8 8 5 3 2 ... $ mc : num 68.1 23 60 53.4 17.5 ... $ mp : num 26.5 18.4 48.7 24.7 1.2 ... $ sc : num 34.9 13 25.5 37.7 12 ... $ sp : num 24.4 8.2 31.2 25.7 1 ... $ yi : num 1.205 0.371 0.431 0.776 0.982 ... ..- attr(*, "ni")= num [1:18] 60 34 87 78 5 48 46 93 10 26 ... ..- attr(*, "slab")= chr [1:18] "1 2015" "2 2007" "3 2023" "4 2013" ... ..- attr(*, "measure")= chr "SMD" $ vi : num 0.197 0.165 0.125 0.129 1.346 ... - attr(*, "digits")= Named num [1:9] 4 4 4 4 4 4 4 4 4 ..- attr(*, "names")= chr [1:9] "est" "se" "test" "pval" ... - attr(*, "yi.names")= chr "yi" - attr(*, "vi.names")= chr "vi"
已尝试的代码
数据准备与模型拟合
seeds_p <- escalc(measure = "SMD", m1i= mc , m2i= mp, sd1i= sc, sd2i= sp, n1i= c, n2i= p, data = seeds, slab = paste(study, year), drop00 = TRUE) # Fit random-effects model using the DL estimator res_p <- rma(yi, vi, data = seeds_p, method = "DL")
绘图及标签尝试(基础版)
radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16, cex = seeds_p$yi * 8 / max(seed_p$yi, na.rm = TRUE), col = seeds$Col, cex.axis = 2, cex.lab = 1.8) par(mar = c(7, 7, 7, 7) + 0.2) # Adjust the values as needed # Extract only the study names without the date study_labels <- gsub("\s\d{4}$", "", seeds$study) # Add labels with basic text and segments text_labels <- data.frame( x = res_p$yi * 4 / max(res_p$yi, na.rm = TRUE), y = sqrt(1 / res_p$vi), label = study_labels) # Add labels with basic text text(text_labels$x, text_labels$y, labels = text_labels$label, pos = 3, col = "black", cex = 0.8) # Add segments connecting points to labels segments( x0 = text_labels$x, y0 = text_labels$y, x1 = res_p$yi * 15 / max(res_p$yi, na.rm = TRUE), y1 = sqrt(1 / res_p$vi), col = "black" )
循环添加标签与线段
# Add labels and connecting lines for (i in 1:nrow(seeds_p)) { x <- res_p$yi[i] * 3 / max(res_p$yi, na.rm = TRUE) y <- sqrt(1 / res_p$vi[i]) # Add label with offset text(x, y, study_labels[i], pos = ifelse(x > 0, 4, 2), col = "black", offset = 1.5) # Add connecting line lines(c(x, x), c(y, 0), col = "black") }
另一版循环写法
# Create radial plot radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16, cex = seeds_p$yi * 3 / max(platelets_p$yi, na.rm = TRUE), col = seeds$Col, cex.axis = 2, cex.lab = 1.8) par(mar = c(7, 7, 7, 7) + 0.2) # Adjust the values as needed # Extract only the study names without the date study_labels <- gsub("\s\d{4}$", "", seeds_p$study) # Add labels and connecting lines for (i in 1:nrow(seeds_p)) { x <- res_p$yi[i] * 3 / max(res_p$yi, na.rm = TRUE) y <- sqrt(1 / res_p$vi[i]) # Add label text(x, y, study_labels[i], pos = 3, col = "black") # Add connecting line lines(c(x, x), c(y, 0), col = "black") }
同时试过ggrepel和directlabels包,但效果不佳。
解决方案
方案1:Base R + calibrate包自动调整标签
calibrate包的textxy函数可自动计算标签最佳位置,避免重叠,同时支持绘制连接线。
# 安装包(首次使用) install.packages("calibrate") library(calibrate) library(metafor) # 绘制径向图 radial(res_p, transf = exp, back = alpha("lightgreen", 0.05), pch = 16, cex = seeds_p$yi * 8 / max(seeds_p$yi, na.rm = TRUE), # 修正变量名错误 col = seeds$Col, cex.axis = 2, cex.lab = 1.8) par(mar = c(7,7,7,7)+0.2) # 提取标签和坐标 study_labels <- gsub("\\s\\d{4}$", "", seeds_p$slab) # 直接从slab提取更准确 x_coords <- res_p$yi y_coords <- sqrt(1/res_p$vi) # 添加自动调整的标签和连接线 textxy(x_coords, y_coords, labs = study_labels, cx = 0.8, col = "black", offset = 0.5, box = FALSE, lines = TRUE, col.lines = "black")
方案2:ggplot2 + ggrepel(更灵活)
若base R方案仍不理想,用ggplot2重绘径向图,结合ggrepel自动处理标签重叠,效果更稳定。
# 安装包(首次使用) install.packages(c("ggplot2", "ggrepel")) library(ggplot2) library(ggrepel) library(metafor) # 整理绘图数据 plot_data <- data.frame( yi = res_p$yi, precision = sqrt(1/res_p$vi), study_label = gsub("\\s\\d{4}$", "", seeds_p$slab), size = seeds_p$yi / max(seeds_p$yi, na.rm = TRUE) * 8, color = seeds$Col ) # 绘制径向图 ggplot(plot_data, aes(x = yi, y = precision)) + # 模拟背景置信区间 geom_ribbon(aes(ymin = 0, ymax = Inf), fill = alpha("lightgreen", 0.05)) + # 添加数据点 geom_point(aes(size = size, color = color), shape = 16) + # 添加自动调整的标签和连接线 geom_text_repel(aes(label = study_label), size = 3, color = "black", segment.color = "black", segment.size = 0.5, box.padding = 0.5, max.overlaps = Inf) + # x轴指数转换 scale_x_continuous(trans = "exp") + # 设置轴标签和主题 labs(x = "Exponential of SMD", y = "Precision (1/sqrt(vi))") + theme_bw() + theme(axis.text = element_text(size = 14), axis.title = element_text(size = 16), plot.margin = margin(20,20,20,20))
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

