You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言如何根据矩阵查找匹配值填充DataFrame的COST列

R语言实现跨表重量档位成本匹配方案

你这个需求本质是宽格式矩阵转长表后做键值匹配,比逐行判断加VLOOKUP的方案扩展性好、运行效率高,也不需要硬编码重量判断阈值。
从你给的样例能看出匹配规则:重量向上匹配最近的重量档位(比如1匹配1档,2-3匹配3档,4-5匹配5档),这个逻辑用向量化函数实现即可,不需要写Weight <1.1这类硬判断。

方案1:tidyverse 实现(代码可读性强,适合日常数据处理)

首先载入样例数据:

# 样例数据
Table1 <- structure(list(X = c("SYD", "MEL", "BRIS"), X1 = c(0.29, 0.4, 0.46), X3 = c(0.4, 0.29, 0.87), X5 = c(0.46, 0.85, 0.29)), class = "data.frame", row.names = c(NA, -3L))
Table2 <- structure(list(FROM = c("SYD", "SYD", "SYD", "MEL", "MEL"), Weight = c(1L, 3L, 4L, 1L, 5L), COST = c(0.29, 0.4, 0.46, 0.4, 0.85)), class = "data.frame", row.names = c(NA, -5L))

第一步先把宽格式的Table1转成标准长表,每一行对应「出发地+重量档位+成本」的唯一组合:

library(dplyr)
library(tidyr)
# 提取所有重量档位并排序
weight_breaks <- sort(as.numeric(gsub("X", "", names(Table1)[-1])))
# 宽转长
Table1_long <- Table1 %>%
  pivot_longer(cols = -X, names_to = "weight_gear", values_to = "COST") %>%
  mutate(weight_gear = as.numeric(gsub("X", "", weight_gear))) %>%
  rename(FROM = X)

第二步给Table2的每条记录匹配对应档位,关联成本:

result <- Table2 %>%
  select(-COST) %>% # 删掉原有空值/临时值列
  mutate(
    # 向上匹配最近档位
    gear_pos = findInterval(Weight, weight_breaks, left.open = TRUE) + 1,
    match_gear = weight_breaks[gear_pos]
  ) %>%
  left_join(Table1_long, by = c("FROM", "match_gear" = "weight_gear")) %>%
  select(FROM, Weight, COST)

运行结果和你给出的预期输出完全一致:

> result
  FROM Weight COST
1  SYD      1 0.29
2  SYD      3 0.40
3  SYD      4 0.46
4  MEL      1 0.40
5  MEL      5 0.85

方案2:base R 实现(无需安装第三方包,适合轻量脚本)

如果不想加载tidyverse依赖,用基础R函数也能实现同样效果:

# 提取重量档位
weight_breaks <- sort(as.numeric(gsub("X", "", colnames(Table1)[-1])))
# 转换Table1为长表
Table1_long <- data.frame(
  FROM = rep(Table1$X, length(weight_breaks)),
  weight_gear = rep(weight_breaks, each = nrow(Table1)),
  COST = unlist(Table1[, -1], use.names = FALSE)
)
# 匹配档位
Table2$gear_pos <- findInterval(Table2$Weight, weight_breaks, left.open = TRUE) + 1
Table2$match_gear <- weight_breaks[Table2$gear_pos]
# 关联匹配成本
Table2$COST <- Table1_long$COST[match(
  paste(Table2$FROM, Table2$match_gear),
  paste(Table1_long$FROM, Table1_long$weight_gear)
)]
# 输出结果
result <- Table2[, c("FROM", "Weight", "COST")]

方案优势

  • 无硬编码阈值:后续新增/修改重量档位,只需要调整Table1的列即可,不需要修改匹配逻辑代码
  • 运行效率高:全向量化操作,处理十万级以上数据比逐行VLOOKUP/循环快10~100倍
  • 规则调整灵活:如果需要改成向下匹配、自定义区间,只需要调整findInterval的参数即可,不需要重构代码

内容的提问来源于stack exchange,提问作者Raul Ravi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 11:01:40