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

R语言:如何匹配数据框食物项并返回对应分类列表名称?

问题描述

我有一个列表对象a,示例如下:

a <- list("FRUITS" = c("apples","bananas","pears"),
          "VEGGIES" = c("lettuce","pepper","carrot"),
          "BREADS" = c("bagel","muffin","sandwhich"))

实际数据包含300个长度不等的子列表,每个子列表约有90个元素。另有一个数据框b(实际含数千行):

b <- data.frame("Sample" = c("BB","TT","LT"),
        "Food" = c("SandWich","Tomato","BANANA"),
        "Volume" = c(124,1356,1343))

目标是为数据框b新增一列Match,填入每个Food项所属的列表名称,要求大小写不敏感匹配,示例结果如下:

data.frame("Sample" = c("BB","TT","LT"),
        "Food" = c("SandWich","Tomato","BANANA"),
        "Volume" = c(124,1356,1343),
        "Match" = c("BREADS","VEGGIES","FRUITS"))

尝试过类似Excel VLOOKUP的方法,但未找到能返回列表名称的方案,请问该如何实现?


解决方案

方法1:基础R实现

核心思路是先将列表a转换为键值对格式的匹配表,统一大小写后再与b进行匹配:

# 把列表a转换为长格式匹配表,统一转小写
lookup_df <- data.frame(
  food = tolower(unlist(a)),
  category = rep(names(a), sapply(a, length)),
  stringsAsFactors = FALSE
)

# 对b的Food列转小写,匹配分类并新增列
b$Match <- lookup_df$category[match(tolower(b$Food), lookup_df$food)]

# 查看结果
print(b)

方法2:tidyverse工具链实现

用purrr和dplyr的语法可以更简洁地完成转换与匹配,适合习惯tidy风格的用户:

library(tidyverse)

# 将列表转为长格式匹配表,统一食物名称大小写
lookup_df <- enframe(a, name = "Match", value = "Food") %>%
  unnest(Food) %>%
  mutate(Food = tolower(Food))

# 匹配并合并到原数据框
b <- b %>%
  mutate(Food_lower = tolower(Food)) %>%
  left_join(lookup_df, by = c("Food_lower" = "Food")) %>%
  select(-Food_lower)

# 查看结果
print(b)

方法3:data.table高效实现(适合大数据量)

如果数据框b行数较多(数千行及以上),data.table的匹配效率会远高于基础R和tidyverse:

library(data.table)

# 转换列表为data.table格式的匹配表
lookup_dt <- rbindlist(
  lapply(names(a), function(x) data.table(Food = tolower(a[[x]]), Match = x))
)

# 转换b为data.table,完成匹配并清理临时列
setDT(b)[, Food_lower := tolower(Food)]
b <- lookup_dt[b, on = .(Food = Food_lower)]
b[, Food_lower := NULL]

# 查看结果
print(b)

注意事项

  • 如果某个Food项同时属于多个分类,以上方法会返回第一个匹配到的分类;若需返回所有匹配分类,可修改代码将结果用逗号分隔。
  • 匹配时必须统一使用tolower()或toupper(),避免因大小写差异导致匹配失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:01:16