如何在R语言的dataframe中批量查找m.z列差值4-6的数据对?
head(peaks) m.z Height RT 1 84.9594 358909 0.219 2 214.9169 111512 0.223 3 56.9418 168197 0.261 4 201.8865 26736 0.352 5 122.9683 20625 0.465 6 84.9594 343573 0.854
我拥有一个dataframe,希望在其中的m.z列中查找所有差值介于4到6之间的数据对。该列包含700余个数据点,无法逐个手动查找,请问是否存在可一次性批量分析整列的函数或R包?目前仅找到对比两个dataframe的函数。
解决方法
下面提供几种在单列中批量查找符合差值条件数据对的实现方式:
基础R实现
利用outer()生成所有数据对的差值矩阵,再筛选符合条件的结果,同时避免重复配对(如(i,j)和(j,i)只保留一组):
# 提取m.z列数据 mz_vals <- peaks$m.z # 生成所有数据对的差值矩阵 diff_matrix <- outer(mz_vals, mz_vals, "-") # 筛选差值在4到6之间,且仅保留i < j的配对(避免重复) matches <- which(diff_matrix >= 4 & diff_matrix <= 6 & upper.tri(diff_matrix), arr.ind = TRUE) # 整理结果为数据框 result <- data.frame( 索引1 = matches[,1], mz值1 = mz_vals[matches[,1]], 索引2 = matches[,2], mz值2 = mz_vals[matches[,2]], 差值 = diff_matrix[matches] ) # 查看前几行结果 head(result)
tidyverse风格实现
如果习惯使用dplyr和tidyr,可以通过生成笛卡尔积后筛选:
library(dplyr) library(tidyr) result <- peaks %>% mutate(索引 = row_number()) %>% select(索引, m.z) %>% expand_grid(., .) %>% # 生成所有数据对 filter(索引.x < 索引.y) %>% # 排除重复配对 mutate(差值 = m.z.y - m.z.x) %>% filter(差值 >= 4 & 差值 <= 6) %>% rename(索引1 = 索引.x, mz值1 = m.z.x, 索引2 = 索引.y, mz值2 = m.z.y) head(result)
data.table高效实现
data.table在处理笛卡尔积时性能更优,适合数据量较大的场景:
library(data.table) setDT(peaks)[, 索引 := .I] result <- peaks[peaks, on = .(), allow.cartesian = TRUE][ 索引 < i.索引, .(索引1 = 索引, mz值1 = m.z, 索引2 = i.索引, mz值2 = i.m.z, 差值 = i.m.z - m.z) ][差值 >= 4 & 差值 <= 6] head(result)
补充说明
如果需要绝对值差值在4到6之间(即不管两个值谁大谁小,差值的绝对值符合条件),只需将筛选条件中的差值 >=4 & 差值 <=6替换为abs(差值) >=4 & abs(差值) <=6即可。
内容的提问来源于stack exchange,提问作者no pe
相关产品推荐
相关产品推荐

