Home > OS >  Join tables with inexact match in R. Only match if a whole word matches
Join tables with inexact match in R. Only match if a whole word matches

Time:01-12

I have a problem that can be reproduced in the following way:

library(tidyverse)
a <- tibble(navn=c("Oslo kommune", "Oslo kommune", "Kommunen i Os", "Kommunen i Eidsberg", "Eid fylkeskommune"), person=c("a", "c", "b", "a", "b"))
b <- tibble(knavn=c("Oslo", "Eid", "Eidsberg", "Os"), tall=c(1,2,3,4))

library(fuzzyjoin)
library(stringr)

c <- a %>%
  fuzzy_left_join(b, by=c("navn"="knavn"), match_fun=str_detect)

I want "Oslo kommune" to match with "Oslo" not with "Os", and "Kommunen i Eidsberg" to match with "Eidsberg" not "Eid". I want the function to look only for whole words in variable navn in a that matches with the word in the variable knavn in b. So that c becomes:

tibble(navn=c("Oslo kommune", "Oslo kommune", "Kommunen i Os", "Kommunen i Eidsberg", "Eid fylkeskommune"), person=c("a", "c", "b", "a", "b"), knavn=c("Oslo","Oslo", "Os", "Eidsberg", "Eid"),tall=c(1,1,4,3,2))

How could I do that?

CodePudding user response:

You can add \\b to capture words:

a %>%
  fuzzy_left_join(b, by = c("navn" = "knavn"), 
                  match_fun = \(x, y) str_detect(x, paste0("\\b", y, "\\b")))

# A tibble: 5 × 4
  navn                person knavn     tall
  <chr>               <chr>  <chr>    <dbl>
1 Oslo kommune        a      Oslo         1
2 Oslo kommune        c      Oslo         1
3 Kommunen i Os       b      Os           4
4 Kommunen i Eidsberg a      Eidsberg     3
5 Eid fylkeskommune   b      Eid          2

If you're working in the tidyverse, glue("\\b{y}\\b") might be better.

CodePudding user response:

A base R alternative using grepl

join_word_match <- function(a, b, first_col, second_col)
  data.frame(do.call(rbind, apply(b, 1, function(x){
    res <- grepl(paste0("\\b", x[second_col], "\\b"), unlist(a[, first_col]))
      do.call(cbind, c(a[res,], x))})))

join_word_match(a, b, "navn", "knavn")
                 navn person    knavn tall
1        Oslo kommune      a     Oslo    1
2        Oslo kommune      c     Oslo    1
3   Eid fylkeskommune      b      Eid    2
4 Kommunen i Eidsberg      a Eidsberg    3
5       Kommunen i Os      b       Os    4
  • Related