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

在R语言中基于查找表按多条件匹配并添加唯一ID

问题描述

现有一个包含大量数据的data.frame(df)和一个参考用的data.frame(lookup),需要根据lookup中的三个条件,为df添加对应的unique_id。

示例数据

目标数据集df

df <- data.frame(fruit = c("mango", "strawberry", "strawberry", "apple", "mango"),
                 size = c(34, 17, 29, 10, 1),
                 var_x = c("X4", "X1", "X1a", "X1", "X1b")
)

数据预览:

fruit size var_x
1      mango   34    X4
2 strawberry   17    X1
3 strawberry   29   X1a
4      apple   10    X1
5      mango    1   X1b

参考查找表lookup

lookup <- data.frame(unique_id = LETTERS[1:7],
                     fruit = c("apple", "apple", "strawberry", "mango", "mango", "mango", "mango"),
                     size = c("1:9", "1:9", "10:40", "1:100", "1:9", "1:9", "10:40"),
                     var_x = c("c('X1', 'X1a', 'X1b')",  "X3", "c('X1', 'X1a', 'X1b')", "c('X1', 'X1a', 'X1b')", "X2", "X3","c('X1', 'X4')")
)

数据预览:

unique_id      fruit  size                 var_x
1         A      apple   1:9 c('X1', 'X1a', 'X1b')
2         B      apple   1:9                    X3
3         C strawberry 10:40 c('X1', 'X1a', 'X1b')
4         D      mango 1:100 c('X1', 'X1a', 'X1b')
5         E      mango   1:9                    X2
6         F      mango   1:9                    X3
7         G      mango 10:40         c('X1', 'X4')

匹配规则与预期输出

匹配需同时满足三个条件:

  • df与lookup的fruit字段完全匹配
  • df$size落在lookup$size指定的数值范围内
  • df$var_x属于lookup$var_x指定的选项集合(支持单个或多个选项)

匹配后为df添加对应unique_id,修正后的正确预期输出:

unique_id      fruit size var_x
1         G      mango   34    X4
2         C strawberry   17    X1
3         C strawberry   29   X1a
4      <NA>      apple   10    X1
5         D      mango    1   X1b
解决方案

核心是解析lookup中的范围表达式和多选项表达式,再逐行匹配条件,实现代码如下:

# 加载依赖包
library(dplyr)
library(purrr)

# 预处理lookup表:解析范围和选项列表
lookup_processed <- lookup %>%
  mutate(
    # 将size范围拆分为最小值和最大值
    size_min = as.integer(sub(":(.*)", "", size)),
    size_max = as.integer(sub("(.*):", "", size)),
    # 解析var_x的表达式为字符向量
    var_x_list = map(var_x, ~eval(parse(text = .x)))
  )

# 定义单条数据的匹配函数
match_unique_id <- function(row_data) {
  # 筛选符合所有条件的lookup记录
  matched_rows <- lookup_processed %>%
    filter(
      fruit == row_data$fruit,
      row_data$size >= size_min,
      row_data$size <= size_max,
      row_data$var_x %in% var_x_list[[1]]
    )
  
  # 返回第一个匹配的unique_id,无匹配则返回NA
  if (nrow(matched_rows) > 0) matched_rows$unique_id[1] else NA_character_
}

# 应用匹配逻辑到df的每一行
result_df <- df %>%
  rowwise() %>%
  mutate(unique_id = match_unique_id(cur_data())) %>%
  ungroup() %>%
  select(unique_id, everything())

# 查看最终结果
print(result_df)

代码说明

  1. 预处理lookup表:

    • 拆分size字段的范围字符串为数值型的size_min和size_max,简化范围判断逻辑
    • 用map结合eval(parse())解析var_x中的表达式,将单个值或多值字符串转换为可直接判断的字符向量
  2. 匹配函数:

    • 对df的每一行,筛选出同时满足三个匹配条件的lookup记录
    • 返回第一个匹配的unique_id,无匹配结果时返回NA
  3. 批量处理数据集:

    • 使用rowwise()逐行处理df,调用匹配函数生成unique_id
    • 调整列顺序,将unique_id放在数据集最前端

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:24:53