PAYATHON 2026

如何在 R 中逐项匹配两列条目并提取对应行的值?

数据小许

可以用 R 自带的 match() 找到每个条目在查找列中的位置,再据此提取对应的值,赋给新列。整个过程按条目匹配,不需要自己写 for 循环。

为什么 match() 适合这个问题?

你描述的两列都包含相同的 40 个条目,只是顺序不同。可以先找到每个条目在查找列中的行位置,再从该行的指定列取值。

match(x, table)

其中,x 是待查找的条目向量,table 是供查找的条目向量。返回结果与 x 等长,每个位置记录对应条目第一次出现在 table 中的位置;找不到时返回 NA。

传入整列时,match() 会逐个查找列中的条目。

在数据框中提取对应值

原问题没有提供实际数据和列名,下面用 4 个条目举例。假设数据框包含:

  • previous_item:供查找的条目列。
  • source_value:与 previous_item 同行、需要提取的值。
  • current_item:需要逐项查找的条目列。
df <- data.frame(
  previous_item = c("A", "B", "C", "D"),
  source_value = c(10, 20, 30, 40),
  current_item = c("C", "A", "D", "B"),
  stringsAsFactors = FALSE
)

# 找到每个 current_item 在 previous_item 中的位置
idx <- match(df$current_item, df$previous_item)

# 提取匹配行的值,并按 current_item 的顺序写入新列
df$matched_value <- df$source_value[idx]

df

结果为:

  previous_item source_value current_item matched_value
1             A           10            C            30
2             B           20            A            10
3             C           30            D            40
4             D           40            B            20

第一行的 current_item 是 C,它位于 previous_item 的第三行。因此,新列第一行取到第三行的 source_value,即 30。其他条目也按同样的方式匹配,原有行顺序不变。

实际使用时,把列名换成自己的列名,也可以将步骤合并为一条语句:

df$matched_value <- df$source_value[
  match(df$current_item, df$previous_item)
]

如果数据来自两个数据框

如果“之前的列表”和“当前的列表”分别存放在两个数据框中,写法类似。假设 previous 包含 item 和 value,current 包含待查找的 item:

current$matched_value <- previous$value[
  match(current$item, previous$item)
]

位置来自 previous$item,因此要从与它逐行对应的 previous$value 中取值。

重复条目和未匹配条目怎么处理?

match() 遇到重复条目时,只返回第一次匹配的位置。如果查找列可能包含同名条目,而且这些行的值不同,需要先确定应该取哪一行。可以先检查查找列是否存在重复值:

anyDuplicated(df$previous_item)

返回 0 表示没有重复值;非零值表示存在重复值。

找不到匹配项时,idx 中相应位置为 NA,提取后的新列通常也会得到 NA。可以单独检查哪些条目没有匹配成功:

idx <- match(df$current_item, df$previous_item)
df$current_item[is.na(idx)]

应通过 idx 判断是否匹配成功,因为 source_value 本身也可能包含 NA。字符匹配区分大小写,前后空格也会影响结果;只有确认这些差异没有业务含义时,才应先统一清理。

如果条目列包含缺失值,还要留意:match() 可以让 NA 匹配到查找列中的 NA。若缺失条目不应参与匹配,可以明确排除:

idx <- match(df$current_item, df$previous_item)
idx[is.na(df$current_item)] <- NA_integer_
df$matched_value <- df$source_value[idx]

备注:内容仅供参考。