如何从ggplot::geom_density_2d_filled聚类层级提取关联患者ID的点?
提取密度聚类区域内的患者ID方案
直接使用ggplot::geom_density_2d_filled无法直接关联原始数据点与聚类区域,因为该图层仅负责可视化,不会将聚类标签绑定到数据集。以下是两种可行的解决思路:
思路1:匹配geom_density_2d_filled的可视化结果,手动绑定聚类标签
通过计算二维密度并判断点所属的等高线区域,实现和原可视化完全对应的聚类提取:
library(MASS) library(sp) library(dplyr) # 计算二维密度(参数n控制精度,数值越大越精细) kde_result <- kde2d(PC_16_mod$Cl_total_18.0, PC_16_mod$pLPE_18.0, n = 100) # 生成与geom_density_2d_filled对应的等高线层级 contour_levels <- quantile(kde_result$z, seq(0.1, 0.9, 0.2)) contour_polygons <- contourLines(kde_result, levels = contour_levels) # 将等高线多边形转换为数据框并分配区域ID poly_data <- lapply(seq_along(contour_polygons), function(idx) { data.frame( x = contour_polygons[[idx]]$x, y = contour_polygons[[idx]]$y, cluster_id = idx ) }) %>% bind_rows() # 为每个患者点匹配所属聚类区域 PC_16_mod$cluster_id <- apply(PC_16_mod, 1, function(row) { point_x <- as.numeric(row["Cl_total_18.0"]) point_y <- as.numeric(row["pLPE_18.0"]) # 遍历每个多边形,判断点是否在内部 for (cid in unique(poly_data$cluster_id)) { poly_sub <- subset(poly_data, cluster_id == cid) in_cluster <- point.in.polygon(point_x, point_y, poly_sub$x, poly_sub$y) if (in_cluster == 1) return(cid) } # 不在任何聚类区域内的点标记为0 return(0) }) # 查看每个聚类内的患者ID列表 PC_16_mod %>% group_by(cluster_id) %>% summarise(patient_list = list(patient_ID))
思路2:改用明确的聚类算法(更适合核心需求)
如果你的核心目标是验证患者是否持续聚集,而非单纯的密度可视化,直接使用聚类算法(如DBSCAN、K-means)更高效,自带聚类标签便于后续分析:
library(dbscan) library(dplyr) library(ggplot2) # 使用DBSCAN进行密度聚类(eps和minPts需根据数据调整) db_cluster <- dbscan(PC_16_mod[, c("Cl_total_18.0", "pLPE_18.0")], eps = 0.3, minPts = 5) PC_16_mod$cluster_id <- db_cluster$cluster # 提取每个聚类的患者ID cluster_patients <- PC_16_mod %>% group_by(cluster_id) %>% summarise(patient_list = list(patient_ID)) # 可视化验证(保留原风格同时标注聚类) ggplot(PC_16_mod, aes(x=Cl_total_18.0, y=pLPE_18.0, color=factor(cluster_id))) + geom_point(size=0.5, shape=16) + geom_density_2d(alpha=0.5)
方案对比
- 思路1完全匹配
geom_density_2d_filled的可视化区域,适合需要和原图一一对应的场景 - 思路2更聚焦聚类分析本身,算法逻辑清晰,后续跨样本验证患者聚集性更方便
内容的提问来源于stack exchange,提问作者Christy
相关产品推荐
相关产品推荐

