How to join two dataframes based on matching word(s) in a string?
02:41 10 Oct 2026

I have a data frame that contains a short description of the origin of a particular specimen, and another data frame that has an index/list of regions and countries that specimens can be sourced from.

For each specimen, I would like to add the region and country by searching the origin description for one of the entries in the index column of the other dataframe; if there is a match, returning that index entry and if there is not a match, just return a blank cell.

# This is the data I have currently
specimen_origin <- data.frame(specimen = c("Specimen 1", "Specimen 2", 
                                           "Specimen 3", "Specimen 4"),
                              origin   = c("Collected on trip to Denver, Colorado", 
                                           "Found in wild at Ohio Botanical Gardens", 
                                           "Cliffside during Yunnan 2002 expedition", 
                                           "Unknown"))



# This is the index of all the places where specimens were collected
country_origin_index <- data.frame(region  = c("Colorado", "Ohio", "Missouri", 
                                               "Texas", "Yunnan", "Chongqing"),
                                   country = c("USA", "USA", "USA", 
                                               "USA", "China", "China"))


# This is the expected output:
specimen_origin_with_location <- data.frame(specimen = c("Specimen 1", "Specimen 2", 
                                                         "Specimen 3", "Specimen 4"),
                                            origin   = c("Collected on trip to Denver, Colorado", 
                                                         "Found in wild at Ohio Botanical Gardens",
                                                         "Cliffside during Yunnan 2002 expedition",
                                                         "Unknown"),
                                            region   = c("Colorado", "Ohio", "Yunnan", ""),
                                            country  = c("USA", "USA", "China", ""))

I know there is probably a way to brute-force it with a very long string of ifelse() and contains functions, but the actual dataset has hundreds of different regions, so I thought there has to be a more efficient way of doing this.

r fuzzyjoin