R语言按ID分组生成字符串两两组合并拆分对应数值列
R实现方案
以下方案基于tidyverse生态实现,完全匹配需求,可直接运行:
完整代码
library(dplyr) library(tidyr) # 输入示例数据 raw_df <- structure(list(Tissue = c("Testis", "Prostate", "Colon - Transverse", "Whole Blood", "Kidney - Cortex", "Prostate", "Kidney - Cortex", "Colon - Transverse", "Testis", "Kidney - Cortex"), ID = c("1", "1", "1", "2", "2", "2", "3", "3", "3", "4"), X = c(-0.0423342169666184, -0.0159575980119219, 0.0653906499828914, 0.0509419093203423, -0.0164593204483257, 0.0128395479305178, -0.0214528156331502, 0.139151567409083, -0.038963750292625, -0.0182265229147926)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -10L), groups = structure(list( ID = c("1", "2", "3", "4"), .rows = structure(list(1:3, 4:6, 7:9, 10L), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -4L), .drop = TRUE)) # 核心处理流程 result <- raw_df %>% ungroup() %>% group_by(ID) %>% # 自动过滤样本数不足2、无法生成配对的分组 filter(n() >= 2) %>% group_modify(~{ # 生成分组内所有行的两两无序不重复组合索引 pair_index <- combn(nrow(.x), 2, simplify = FALSE) # 遍历索引提取对应值,生成结构化结果 lapply(pair_index, function(i){ tibble( `Tissue Pairs` = paste(.x$Tissue[i[1]], .x$Tissue[i[2]], sep = " "), X = .x$X[i[1]], X2 = .x$X[i[2]] ) }) %>% bind_rows() }) %>% ungroup()
逻辑说明
- 用基础R自带的
combn()函数生成两两无序组合,天然保证组内配对不重复,不会出现A-B和B-A同时存在的冗余结果,不同ID组的配对重复会被保留,符合要求 - 配对生成时同步按索引匹配X值,不会出现组织和数值错配的问题
- 针对给出的演示小样例(A/B/C/D那组),运行代码后输出结果和期望结构完全一致
可选调整
- 如果需要修改Tissue配对的拼接分隔符,直接修改
paste()函数里的sep参数即可,比如sep = "_"就会生成类似A_B的配对格式 - 如果需要保留组内只有1个样本的ID记录,删除
filter(n() >= 2)这行代码,自行补充缺失值填充逻辑即可 - 代码仅依赖dplyr、tidyr两个通用数据处理包,无额外特殊依赖。
内容的提问来源于stack exchange,提问作者blue beryl
相关产品推荐
相关产品推荐

