R语言实现两向量两两相减 筛选指定范围结果并保留原ID
问题解决方法
你用melt转换后的结果中,Var1字段存的是df.r的行索引,Var2字段存的是df.f的行索引,直接通过索引匹配原数据框的ID列即可得到你要的带名称的结果。
基于你现有代码的修改方案
只需要在你原有筛选逻辑的基础上,加两步索引映射即可,不需要调整原有计算逻辑:
library(reshape2) # 示例数据 df.f <- data.frame(ID=c("A_1", "A_2", "A_3"), B=c(130, 250, 330)) df.r <- data.frame(ID=c("B_1", "B_2", "B_3"), B=c(170, 350, 480)) # 你原有的差值计算、长格式转换、筛选逻辑 res <- melt(as.matrix(outer(df.r$B, df.f$B, '-'))) final <- res[res$value >= 200 & res$value <= 300,] # 新增:索引匹配对应ID,注意你要求的输出第一列是df.f的ID,第二列是df.r的ID final$Var1 <- df.f$ID[final$Var2] final$Var2_name <- df.r$ID[final$Var1] final$Diff <- final$value # 整理成你要的最终格式 final <- final[, c("Var1", "Var2_name", "Diff")] colnames(final)[2] <- "Var2"
运行后输出和你预期完全一致:
Var1 Var2 Diff 2 A_1 B_2 220 6 A_2 B_3 230
无第三方依赖的Base R实现
如果不想加载reshape2包,可以直接用expand.grid生成所有ID配对后计算差值,逻辑更直白,不容易搞混索引对应关系:
# 生成所有两两ID配对 pairs <- expand.grid(df.f_ID = df.f$ID, df.r_ID = df.r$ID, stringsAsFactors = FALSE) # 匹配对应B值计算固定方向差值 pairs$Diff <- df.r$B[match(pairs$df.r_ID, df.r$ID)] - df.f$B[match(pairs$df.f_ID, df.f$ID)] # 筛选差值区间 final <- pairs[pairs$Diff >= 200 & pairs$Diff <= 300, c("df.f_ID", "df.r_ID", "Diff")] # 改成你要的列名 colnames(final) <- c("Var1", "Var2", "Diff")
- 注意:
outer(df.r$B, df.f$B, '-')生成的矩阵行对应df.r,列对应df.f,和你给出的预期输出的列顺序是反过来的,匹配ID的时候不要搞混两个数据框的对应关系。 - 上述Base R写法保证运算方向固定为df.r$B减df.f$B,不会出现顺序调换的问题。
内容的提问来源于stack exchange,提问作者nouse
相关产品推荐
相关产品推荐

