如何基于行名第4个分隔符前的子串匹配合并二进制矩阵行?
二进制矩阵按行名前缀合并行的实现方案
需求说明
给定一个元素仅为0和1的二进制矩阵,需按以下规则处理:
- 以行名中第4个
.分隔符为分界,保留分隔符之前的前缀部分;前缀相同的行归为一组进行合并 - 合并规则:组内任意一行的某列值为1时,合并后该行该列值即为1
- 最终结果的行名仅保留第4个
.之前的前缀部分
示例数据
df <- structure(list(DNMT3A = c(1, 0, 0, 0, 0), IGF2R = c(1, 0, 0, 0, 1), NBEA = c(1, 0, 0, 0, 1), ITGB5 = c(0, 1, 0, 0, 0)), row.names = c("TCGA.2Z.A9J1.01A.11D.A382.10", "TCGA.B9.A5W9.01A.11D.A28G.10", "TCGA.2Z.A9JM.01A.13D.A44J.12", "TCGA.GL.A59R.01A.11D.A26P.10", "TCGA.2Z.A9JM.01A.12D.A42J.10"), class = "data.frame")
期望输出
structure(list(DNMT3A = c(1, 0, 0, 0), IGF2R = c(1, 0, 1, 0), NBEA = c(1, 0, 1, 0), ITGB5 = c(0, 1, 0, 0)), row.names = c("TCGA.2Z.A9J1.01A", "TCGA.B9.A5W9.01A", "TCGA.2Z.A9JM.01A", "TCGA.GL.A59R.01A"), class = "data.frame")
实现代码(R语言)
# 提取行名的前缀(保留第4个.之前的部分) row_prefixes <- sub("^(([^.]+\\.){3}[^.]+).*", "\\1", rownames(df)) # 按前缀分组,对每列取最大值(满足"有1则为1"的合并逻辑) merged_df <- aggregate(. ~ row_prefixes, data = cbind(row_prefixes, df), FUN = max) # 调整行名并移除辅助列 rownames(merged_df) <- merged_df$row_prefixes merged_df$row_prefixes <- NULL # 查看最终结果 print(merged_df)
代码说明
- 提取前缀:使用正则表达式
^(([^.]+\\.){3}[^.]+).*匹配行名,捕获前4段内容(即第4个.之前的部分),通过sub函数替换得到所有行的前缀。 - 分组合并:用
aggregate函数按前缀分组,对每组的列值取最大值——因为矩阵元素只有0和1,最大值为1就意味着组内至少有一行该列是1,正好符合合并规则。 - 结果整理:将分组后的前缀设置为新行名,移除用于分组的辅助列,得到最终的合并矩阵。
内容的提问来源于stack exchange,提问作者melolilili
相关产品推荐
相关产品推荐

