基于5个蛋白质亚基的3D坐标计算点间距离并确定环状排列顺序
基于5个蛋白质亚基的3D坐标计算点间距离并确定环状排列顺序
嗨,Hanna!很高兴看到你第一次发帖,要是下面的方案有任何不可复现的问题,随时跟我说哈~
第一步:先把坐标数据整理到位
首先咱们把你的坐标数据调整成更直观的格式,每一行对应一个亚基,包含x、y、z三个坐标列,后续处理会更顺手:
# 构建规范的坐标数据框 coordinates <- data.frame( subunit = c("A", "B", "C", "D", "E"), x = c(15, -13, 33, -18, -13), y = c(-33, -55, -42, -53, -42), z = c(-44, -8, -19, -1, -35) ) # 查看整理后的数据 coordinates
第二步:计算亚基间的3D欧氏距离
3D空间里两点的直线距离就是欧氏距离,我们可以用dist()函数直接生成所有亚基两两之间的距离矩阵:
# 提取坐标列,计算距离矩阵 dist_matrix <- dist(coordinates[, c("x", "y", "z")], method = "euclidean") # 转换为矩阵格式方便查看 dist_matrix <- as.matrix(dist_matrix) # 给行列命名为亚基名称,更清晰 rownames(dist_matrix) <- coordinates$subunit colnames(dist_matrix) <- coordinates$subunit # 查看距离矩阵 dist_matrix
矩阵里的每个值就是对应两个亚基的3D直线距离,比如dist_matrix["A", "E"]就是亚基A和E之间的距离。
第三步:用贪心算法推导环状排列顺序
环状排列的核心是每个亚基只和相邻的两个亚基距离最近(首尾还要相连)。我们用贪心策略来推导:
- 随便选一个起始亚基(比如从A开始)
- 每次从当前亚基的未访问邻居中,选距离最近的那个作为下一个亚基
- 重复直到所有亚基都被选中
- 最后验证首尾亚基的距离是否符合环状闭合的逻辑
代码实现如下:
# 初始化变量 visited <- c() current_subunit <- "A" # 起始点可以任意选,这里选A total_subunits <- nrow(coordinates) # 循环推导顺序 while(length(visited) < total_subunits) { visited <- c(visited, current_subunit) # 筛选出未访问的亚基 unvisited <- setdiff(coordinates$subunit, visited) if(length(unvisited) == 0) break # 找到当前亚基距离最近的未访问亚基 distances <- dist_matrix[current_subunit, unvisited] current_subunit <- names(which.min(distances)) } # 输出推导结果并验证首尾距离 cat("推导的环状顺序(首尾相连):", paste(visited, collapse = "-"), "\n") cat("首尾亚基", visited[1], "和", visited[length(visited)], "之间的距离:", dist_matrix[visited[1], visited[length(visited)]], "\n")
运行后你会得到类似A-E-B-D-C的顺序,同时能看到首尾亚基的距离是否符合环状的预期。
第四步:把环状顺序添加到原数据框
我们给原数据框新增一列ring_order,标记每个亚基在环状排列中的位置:
# 创建顺序映射表 order_map <- data.frame( subunit = visited, ring_order = 1:length(visited) ) # 合并到原数据框并按环状顺序排序 coordinates_with_order <- merge(coordinates, order_map, by = "subunit") coordinates_with_order <- coordinates_with_order[order(coordinates_with_order$ring_order), ] # 查看带顺序的最终数据 coordinates_with_order
第五步:可视化验证环状顺序
你可以用gg3D把亚基按顺序连线,直观确认是不是符合你看到的环状结构:
# 安装并加载所需包 devtools::install_github("AckerDWM/gg3D") library(gg3D) library(ggplot2) # 复制第一行到末尾,实现环状首尾连线 coordinates_plot <- rbind(coordinates_with_order, coordinates_with_order[1, ]) # 绘制3D图,标记亚基并按顺序连线 ggplot(coordinates_plot, aes(x = x, y = y, z = z)) + theme_void() + axes_3D() + stat_3D(aes(color = subunit), size = 5) + # 绘制亚基圆点 stat_3D(geom = "line", aes(group = 1), color = "black") # 按环状顺序连线
备注:内容来源于stack exchange,提问作者Hanna Sahlström
相关产品推荐
相关产品推荐

