R语言编写嵌套循环实现两张质谱化合物表的m/z与RT匹配
现有代码错误说明
- 语法层面错误:
- if判断条件必须包裹在小括号内,你原代码
if abs(Table_1$RT[i]- Table_2$RT[j])<0.9 ==TRUE)缺少左侧括号,同时多了冗余的==TRUE判断 - 大括号配对完全混乱:两层for循环、if/else结构的大括号没有对应闭合,是报错的直接原因
- 逻辑层面错误:
- 仅校验了RT匹配规则,完全没有加入m/z的匹配判断
- m/z匹配规则中你写的
*106是笔误,ppm对应百万分之一,应该为*1e6,同时原公式多了一个多余的右括号
- 数据操作错误:
- 未提前初始化结果表
Table_3,每次赋值直接覆盖整列内容,无法累加所有匹配结果
修正后的实现代码
嵌套循环版本(兼容你原来的思路)
# 提前初始化结果表,固定列结构 Table_3 <- data.frame( ID_T1 = integer(), RT_T1 = numeric(), mz_T1 = numeric(), ID_T2 = integer(), RT_T2 = numeric(), mz_T2 = numeric(), RT_match = logical(), mz_match = logical() ) # 给原表提前初始化匹配标记列,默认值为FALSE Table_1$has_match <- FALSE Table_2$has_match <- FALSE # 嵌套循环匹配 for (i in 1:nrow(Table_1)) { for (j in 1:nrow(Table_2)) { # 同时判断RT和m/z的匹配规则 rt_match <- abs(Table_1$RT[i] - Table_2$RT[j]) < 0.9 mz_match <- abs((Table_1$m.z[i] - Table_2$m.z[j])/Table_1$m.z[i] * 1e6) < 3 if (rt_match & mz_match) { # 匹配成功则追加行到结果表 new_row <- data.frame( ID_T1 = Table_1$ID_T1[i], RT_T1 = Table_1$RT[i], mz_T1 = Table_1$m.z[i], ID_T2 = Table_2$ID_T2[j], RT_T2 = Table_2$RT[j], mz_T2 = Table_2$m.z[j], RT_match = rt_match, mz_match = mz_match ) Table_3 <- rbind(Table_3, new_row) # 标记原表匹配状态 Table_1$has_match[i] <- TRUE Table_2$has_match[j] <- TRUE } } }
更高效的模糊连接版本(避免嵌套循环,适合大数据量)
library(fuzzyjoin) Table_3 <- fuzzy_join( x = Table_1, y = Table_2, by = c("RT", "m.z"), match_fun = list( \(x,y) abs(x-y) < 0.9, \(x,y) abs((x-y)/x *1e6) <3 ), mode = "inner" ) # 匹配完成后给原表加标记列 Table_1$has_match <- Table_1$ID_T1 %in% Table_3$ID_T1 Table_2$has_match <- Table_2$ID_T2 %in% Table_3$ID_T2
需求实现说明
- 新生成的
Table_3已经保留了两个表的所有字段,包括两个实验室分配的ID字段 - 上述代码已经为
Table_1和Table_2新增了has_match列,直接记录该行是否存在匹配记录(TRUE/FALSE),满足你回写原表的需求
匹配结果参考示意图

内容的提问来源于stack exchange,提问作者bsaleeby
相关产品推荐
相关产品推荐

