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

如何基于Species列前两词匹配合并两个大数据量DataFrame?

基于物种学名前两个单词合并大数据量DataFrame的实现方法

我有两个DataFrame需要基于Species列合并:

  • DataFrame 1的Species列仅包含物种名称的前两个单词
  • DataFrame 2的Species列是带命名人信息的完整学名
    要求仅通过Species列的前两个单词进行匹配(例如Themeda triandra与Themeda triandra Forssk.视为匹配),需处理大数据量(df1共32,931行,df2共16,185行),无匹配项标记为NA。

示例数据

DataFrame 1:

Species
Themeda australis
Themeda avenacea
Themeda quadrivalvis
Themeda triandra
Lomandra juncea
Lomandra longifolia

DataFrame 2:

SpeciesCommon_name
Themeda australis (R.Br.) StapfKangaroo grass
Themeda avenacea (F.Muell.) LuggerNative oat
Themeda quadrivalvis (L.) Kuntze.Grader grass
Themeda triandra Forssk.Kangaroo grass
Lomandra juncea (F.Muell.) EwartDesert Mat-rush
Lomandra longifolia Labill.Spiny-headed Mat-rush

数据定义代码:

df1 <- data.frame(Species =  c(
  "Themeda australis",
  "Themeda avenacea",
  "Themeda quadrivalvis",
  "Themeda triandra",
  "Lomandra juncea",
  "Lomandra longifolia"
))
df2 <- data.frame(Species = c(
  "Themeda australis (R.Br.) Stapf",
  "Themeda avenacea (F.Muell.) Lugger",
  "Themeda quadrivalvis (L.) Kuntze.",
  "Themeda triandra Forssk.",
  "Lomandra juncea (F.Muell.) Ewart",
  "Lomandra longifolia Labill."
), Common_name = c(
  "Kangaroo grass",
  "Native oat",
  "Grader grass",
  "Kangaroo grass",
  "Desert Mat-rush",
  "Spiny-headed Mat-rush"
))

期望输出

SpeciesCommon_name
Themeda australisKangaroo grass
Themeda avenaceaNative oat
Themeda quadrivalvisGrader grass
Themeda triandraKangaroo grass
Lomandra junceaDesert Mat-rush
Lomandra longifoliaSpiny-headed Mat-rush

原尝试代码(未得到理想结果)

output <- df1 %>%
  fuzzy_inner_join(df2, by = "Species", match_fun = str_detect)

解决方案

问题原因

原代码的str_detect匹配逻辑颠倒:fuzzy_inner_join默认用match_fun(left_col, right_col),即检查df1的Species是否包含df2的Species,这显然不符合需求;更关键的是,模糊匹配对大数据量效率极低,推荐先提取匹配键再做精确匹配。

方法1:提取匹配键后精确匹配(高效,适合大数据量)

给df2提取Species列的前两个单词作为匹配键,再用left_join完成合并,无匹配项自动标记为NA:

library(tidyverse)

# 处理df2,提取前两个单词作为匹配键
df2_processed <- df2 %>%
  mutate(match_key = str_extract(Species, "^\\w+ \\w+"))

# 合并并整理列
output <- df1 %>%
  left_join(df2_processed, by = c("Species" = "match_key")) %>%
  select(Species = Species.x, Common_name)

方法2:Base R实现(无需加载tidyverse)

# 给df2生成匹配键
df2$match_key <- sapply(strsplit(df2$Species, " "), function(x) paste(x[1:2], collapse = " "))

# 合并并筛选列
output <- merge(df1, df2, by.x = "Species", by.y = "match_key", all.x = TRUE)[, c("Species", "Common_name")]

方法3:修正模糊匹配(仅适合小数据量)

如果一定要用模糊匹配,需调整match_fun的参数顺序,但大数据量下不推荐:

library(fuzzyjoin)
library(stringr)

output <- df1 %>%
  fuzzy_left_join(df2, by = "Species", match_fun = function(x, y) str_detect(y, x)) %>%
  select(Species = Species.x, Common_name)

以上方法均可得到符合期望的输出,其中方法1和2效率更高,适合处理你的大数据量需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 18:47:04