R语言中样本匹配:关联不同标识的表达量dataframe
匹配两个基因表达DataFrame并合并的解决方案
问题描述
现有两个结构相似的基因表达DataFrame,分别使用不同的样本标识(sample和sample2),表达量数据相近。需要按基因分组,为每个样本的基因表达量找到另一个DataFrame中最匹配的表达量,并关联对应的样本标识,最终合并成目标格式的数据集。
示例数据
第一个DataFrame:
gene <- c("a", "b", "c", "a", "b", "c", "a", "b", "c") sample <- c("a", "a", "a", "b", "b", "b", "c", "c", "c") expression <- c("5", "6", "8", "3", "5", "7", "7", "8", "9") df1 <- data.frame(gene, sample, expression)
输出:
gene sample expression 1 a a 5 2 b a 6 3 c a 8 4 a b 3 5 b b 5 6 c b 7 7 a c 7 8 b c 8 9 c c 9
第二个DataFrame:
gene2 <- c("a", "b", "c", "a", "b", "c", "a", "b", "c") sample2 <- c("1", "1", "1", "2", "2", "2", "3", "3", "3") expression2 <- c("5.4", "6.3", "8", "3.2", "5.4", "7.2", "7.1", "8.2", "9.4") df2 <- data.frame(gene2, sample2, expression2)
输出:
gene2 sample2 expression2 1 a 1 5.4 2 b 1 6.3 3 c 1 8 4 a 2 3.2 5 b 2 5.4 6 c 2 7.2 7 a 3 7.1 8 b 3 8.2 9 c 3 9.4
期望合并结果:
gene sample sample2 expression expression2 1 a a 1 5 5.4 2 b a 1 6 6.3 3 c a 1 8 8 4 a b 2 3 3.2 5 b b 2 5 5.4 6 c b 2 7 7.2 7 a c 3 7 7.1 8 b c 3 8 8.2 9 c c 3 9 9.4
解决方案
方法1:使用dplyr+purrr实现分组匹配
适合熟悉tidyverse语法的场景,步骤清晰:
- 转换表达量为数值型(原始数据为字符型,无法计算差值),统一基因列名:
library(dplyr) library(purrr) # 转换数据类型 df1$expression <- as.numeric(df1$expression) df2$expression2 <- as.numeric(df2$expression2) # 统一基因列名 colnames(df2)[colnames(df2) == "gene2"] <- "gene"
- 按基因分组,为每个表达量找到匹配的最小差值行:
merged_df <- df1 %>% group_by(gene) %>% mutate( # 对当前基因的每个表达量,找到df2中差值最小的行索引 match_idx = map_int(expression, ~ which.min(abs(df2$expression2[df2$gene == cur_group()$gene] - .x))), # 提取匹配的样本标识和表达量 sample2 = df2$sample2[df2$gene == cur_group()$gene][match_idx], expression2 = df2$expression2[df2$gene == cur_group()$gene][match_idx] ) %>% ungroup() %>% select(gene, sample, sample2, expression, expression2) # 查看结果 print(merged_df)
方法2:使用data.table滚动连接(适合大规模数据集)
data.table的滚动连接效率极高,适合处理大规模数据:
- 转换数据类型并统一列名:
library(data.table) setDT(df1) setDT(df2) df1[, expression := as.numeric(expression)] df2[, expression2 := as.numeric(expression2)] setnames(df2, "gene2", "gene")
- 按基因分组执行滚动连接(
roll="nearest"表示找最近值):
merged_dt <- df2[df1, on = .(gene, expression2 = expression), roll = "nearest", .(gene, sample = i.sample, sample2 = x.sample2, expression = i.expression, expression2 = x.expression2)] # 查看结果 print(merged_dt)
两种方法均可得到目标格式的合并数据集,其中data.table方法在处理百万级以上数据时优势明显。
内容的提问来源于stack exchange,提问作者szmple
相关产品推荐
相关产品推荐

