【问题标题】:How can I join data using a fuzzy match in R?如何在 R 中使用模糊匹配连接数据?
【发布时间】:2019-11-16 09:30:15
【问题描述】:

我有一些主题和许可证数据,并想创建一个列来标记许可证是否适合列出的主题。额外的挑战是一些教师教授多个科目,用分号分隔,并且每个许可证都有几个可接受的科目。

我认为我需要合并诸如 grep 之类的东西,但我不太确定如何添加此功能,同时还要加入来自两个表的数据。

示例代码

以下是我的数据框的摘录:

df1 <- data.frame(Subject = c("Spanish Language Arts; I teach all subjects for my students", 
"Math; Science", "Mathematics; ELA", "ELA", "Science;Math;English Language Arts", 
"Spanish Language Arts; I teach all subjects for my students",
 "Math", "Science;Social Studies;Mathematics;English Language Arts", "ELA", 
"English Language Arts"), 
Licensure = c("Content Area - Early Childhood (preK-Grade 3)", 
"Core Subjects (Grades EC-6) 1770", "Mathematics (Grades 7-12) 1706", 
"English Language Arts and Reading (Grades 7-12) 1709", "Core Subjects (Grades EC-6) 1770", 
"English Language Arts and Reading (Grades 7-12) 1709", 
"English Language Arts and Reading (Grades 7-12) 1709", 
"Content Area - Elementary Education (Grades 1-6)", 
"Mathematics (Grades 7-12) 1706", "Content Area - Elementary Education (Grades 1-6)"))

这是我创建的列表,其中包括所有许可证以及每个许可证下的可接受程序:

lic.subject_index <- list(
  "Content Area - Early Childhood (preK-Grade 3)" = c("I teach all subjects for my students", "Math", "Mathematics", "ELA", "English Language Arts", "Language Arts"),
  "Content Area - Elementary Education (Grades 1-6)" = c("I teach all subjects for my students", "Math", "Mathematics", "ELA", "English Language Arts", "Language Arts"),
  "Core Subjects (Grades EC-6) 1770" = c("I teach all subjects for my students", "Math", "Mathematics", "ELA", "English Language Arts", "Language Arts"),
  "English Language Arts and Reading (Grades 7-12) 1709" = c("ELA", "English Language Arts", "Language Arts"),
  "Mathematics (Grades 7-12) 1706" = c("Math", "Mathematics")
)

我希望能够创建一个列来标记主题/许可证组合是否可接受:

ideal.df <- data.frame(Subject = c("Spanish Language Arts; I teach all subjects for my students", 
"Math; Science", "Mathematics; ELA", "ELA", "Science;Math;English Language Arts", 
"Spanish Language Arts; I teach all subjects for my students", "Math", 
"Science;Social Studies;Mathematics;English Language Arts", "ELA", "English Language Arts"), 
Licensure = c("Content Area - Early Childhood (preK-Grade 3)", "Core Subjects (Grades EC-6) 1770", 
"Mathematics (Grades 7-12) 1706", "English Language Arts and Reading (Grades 7-12) 1709", 
"Core Subjects (Grades EC-6) 1770", "English Language Arts and Reading (Grades 7-12) 1709", 
"English Language Arts and Reading (Grades 7-12) 1709", "Content Area - Elementary Education (Grades 1-6)", 
"Mathematics (Grades 7-12) 1706", "Content Area - Elementary Education (Grades 1-6)"), 
flag = c("True", "True", "True", "True", "True", "False", "False", "True", "False", "True"))

提前感谢您提供的任何帮助!

【问题讨论】:

    标签: r fuzzy-search


    【解决方案1】:

    这是tidyversefuzzyjoin 的选项

    library(fuzzyjoin)
    library(tidyverse)
    out <- df1 %>%
           rownames_to_column('rn') %>% 
           separate_rows(Subject, sep = ';') %>% 
           stringdist_left_join(
             enframe(lic.subject_index, name = 'Licensure', value = 'Subject') %>% 
                  unnest) %>% 
           group_by(rn = as.integer(rn)) %>%
           summarise(ind = any(!is.na(Licensure.y))) %>%
           ungroup %>% 
           pull(ind) %>% 
           mutate(df1, flag = .)
    out$flag
    #[1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE
    

    -检查 OP 的理想输出

    as.logical(ideal.df$flag)
    #[1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE
    

    【讨论】:

    • 谢谢@akrun。当我将此代码合并到我的完整数据集中时,会​​弹出一条错误消息:下标分配中不允许使用 NA。有没有办法解决 NA,因为我仍然希望看到那些没有执照的老师列出来?很抱歉没有将 NA 合并到我的示例中 - 在我运行此代码之前我没有考虑过!
    • @K.C.可能是您通过删除NA(带有is.na)来过滤数据集,然后使用它来进行连接。
    • 谢谢。理想情况下,我希望将 NA 保留在数据集中,但出于我的目的,我可以执行此过滤器。当我尝试时,您的代码有效。
    猜你喜欢
    • 2017-01-31
    • 2020-03-22
    • 1970-01-01
    • 2018-04-26
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 2022-01-06
    相关资源
    最近更新 更多