在附属机构中查找城市名称,并将它们与相应的国家/地区一起添加到数据框的新列中

Find city names within affiliations and add them with their corresponding countries in new columns of a dataframe

我有一个包含城市名称的隶属关系数据框“dfa”,有时会缺少国家/地区,例如像第 4 行(BAGHDAD)和第 7 行(BERLIN):

dfa <- data.frame(affiliation=c("DEPARTMENT OF PHARMACY, AMSTERDAM UNIVERSITY, AMSTERDAM, THE NETHERLANDS",
                                "DEPARTMENT OF BIOCHEMISTRY, LADY HARDINGE MEDICAL COLLEGE, NEW DELHI, INDIA.",
                                "DEPARTMENT OF PATHOLOGY, CHILDREN'S HOSPITAL, LOS ANGELES, UNITED STATES",
                                "COLLEGE OF EDUCATION FOR PURE SCIENCE, UNIVERSITY OF BAGHDAD.",
                                "DEPARTMENT OF CLINICAL LABORATORY, BEIJING GENERAL HOSPITAL, BEIJING, CHINA.",
                                "LABORATORY OF MOLECULAR BIOLOGY, ISTITUTO ORTOPEDICO, MILAN, ITALY.",
                                "DEPARTMENT OF AGRICULTURE, BERLIN INSTITUTE OF HEALTH, BERLIN",
                                "INSTITUTE OF LABORATORY MEDICINE, UNIVERSITY HOSPITAL, MUNICH, GERMANY.",
                                "DEPARTMENT OF CLINICAL PATHOLOGY, MAHIDOL UNIVERSITY, BANGKOK, THAILAND.",
                                "DEPARTMENT OF BIOLOGY, WASEDA UNIVERSITY, TOKYO, JAPAN",
                                "DEPARTMENT OF MOLECULAR BIOLOGY, MINISTRY OF HEALTH, TEHRAN, IRAN.",
                                "LABORATORY OF CARDIOVASCULAR DISEASE, FUWAI HOSPITAL, BEIJING, CHINA."))

我现在有第二个数据框“dfb”,其中包含城市列表和相应的国家/地区,其中一些出现在 'dfa':

dfb <- data.frame(city=c("AGRI","AMSTERDAM","ATHENS","AUCKLAND","BUENOS AIRES","BEIJING","BAGHDAD","BANGKOK","BERLIN","BUDAPEST"),
                  country=c("TURKEY","NETHERLANDS","GREECE","NEW ZEALAND","ARGENTINA","CHINA","IRAQ","THAILAND","GERMANY","HUNGARY"))

我如何才能在两个新列中仅针对“dfa”和“dfb”中都存在的城市添加城市和相应的国家(即使国家/地区缺失,如 BAGHDAD 和 BERLIN)?

注意:目标是添加 完整 个城市名称,但 不是其中的一部分 。下面第 7 行是一个不想要的示例:土耳其农业城市与柏林不恰当地关联,因为该行包含 'AGRICULTURE' 词。

有没有简单的方法,最好使用 dplyr?

    affiliation      city     country
1      DEPARTMENT OF PHARMACY, AMSTERDAM UNIVERSITY, AMSTERDAM, THE NETHERLANDS AMSTERDAM NETHERLANDS
2  DEPARTMENT OF BIOCHEMISTRY, LADY HARDINGE MEDICAL COLLEGE, NEW DELHI, INDIA.      <NA>        <NA>
3      DEPARTMENT OF PATHOLOGY, CHILDREN'S HOSPITAL, LOS ANGELES, UNITED STATES      <NA>        <NA>
4                 COLLEGE OF EDUCATION FOR PURE SCIENCE, UNIVERSITY OF BAGHDAD.   BAGHDAD        IRAQ
5  DEPARTMENT OF CLINICAL LABORATORY, BEIJING GENERAL HOSPITAL, BEIJING, CHINA.   BEIJING       CHINA
6           LABORATORY OF MOLECULAR BIOLOGY, ISTITUTO ORTOPEDICO, MILAN, ITALY.      <NA>        <NA>
7                 DEPARTMENT OF AGRICULTURE, BERLIN INSTITUTE OF HEALTH, BERLIN      AGRI      TURKEY
8       INSTITUTE OF LABORATORY MEDICINE, UNIVERSITY HOSPITAL, MUNICH, GERMANY.      <NA>        <NA>
9      DEPARTMENT OF CLINICAL PATHOLOGY, MAHIDOL UNIVERSITY, BANGKOK, THAILAND.   BANGKOK    THAILAND
10                       DEPARTMENT OF BIOLOGY, WASEDA UNIVERSITY, TOKYO, JAPAN      <NA>        <NA>
11           DEPARTMENT OF MOLECULAR BIOLOGY, MINISTRY OF HEALTH, TEHRAN, IRAN.      <NA>        <NA>
12        LABORATORY OF CARDIOVASCULAR DISEASE, FUWAI HOSPITAL, BEIJING, CHINA.   BEIJING       CHINA

str_extract 与连接或另一个 str_extract 的组合是实现目标的一种选择。 str_extract 将获取它遇到的第一个值,使用 paste0 将城市折叠成一个长 or 字符串以供检查。

library(dplyr)
library(stringr)

dfa %>% 
  mutate(city = str_extract(dfa$affiliation, paste0("\b", dfb$city, collapse = "\b|"))) %>% 
  left_join(dfb, by = "city")

编辑:在 paste0 中添加了单词边界,以便只匹配整个城市名称,避免部分匹配。

    affiliation      city     country
1      DEPARTMENT OF PHARMACY, AMSTERDAM UNIVERSITY, AMSTERDAM, THE NETHERLANDS AMSTERDAM NETHERLANDS
2  DEPARTMENT OF BIOCHEMISTRY, LADY HARDINGE MEDICAL COLLEGE, NEW DELHI, INDIA.      <NA>        <NA>
3      DEPARTMENT OF PATHOLOGY, CHILDREN'S HOSPITAL, LOS ANGELES, UNITED STATES      <NA>        <NA>
4                 COLLEGE OF EDUCATION FOR PURE SCIENCE, UNIVERSITY OF BAGHDAD.   BAGHDAD        IRAQ
5  DEPARTMENT OF CLINICAL LABORATORY, BEIJING GENERAL HOSPITAL, BEIJING, CHINA.   BEIJING       CHINA
6           LABORATORY OF MOLECULAR BIOLOGY, ISTITUTO ORTOPEDICO, MILAN, ITALY.      <NA>        <NA>
7                 DEPARTMENT OF AGRICULTURE, BERLIN INSTITUTE OF HEALTH, BERLIN    BERLIN     GERMANY
8       INSTITUTE OF LABORATORY MEDICINE, UNIVERSITY HOSPITAL, MUNICH, GERMANY.      <NA>        <NA>
9      DEPARTMENT OF CLINICAL PATHOLOGY, MAHIDOL UNIVERSITY, BANGKOK, THAILAND.   BANGKOK    THAILAND
10                       DEPARTMENT OF BIOLOGY, WASEDA UNIVERSITY, TOKYO, JAPAN      <NA>        <NA>
11           DEPARTMENT OF MOLECULAR BIOLOGY, MINISTRY OF HEALTH, TEHRAN, IRAN.      <NA>        <NA>
12        LABORATORY OF CARDIOVASCULAR DISEASE, FUWAI HOSPITAL, BEIJING, CHINA.   BEIJING       CHINA

这种方法考虑了一个从属关系可以匹配多个城市名称的可能性。

library(tidyverse)

dfa %>% 
  mutate(city = map(affiliation, ~ str_extract(.x, dfb$city))) %>% 
  unnest(cols = c(city)) %>% 
  group_by(affiliation) %>% 
  mutate(nmatches = sum(!is.na(city))) %>% 
  filter((nmatches > 0 & !is.na(city)) | (nmatches == 0 & row_number() == 1)) %>%
  ungroup() %>% 
  left_join(dfb, by = "city") %>% 
  mutate(country_match = str_detect(affiliation, country))

# A tibble: 12 x 5
   affiliation              city   nmatches country country_match
   <chr>                    <chr>     <int> <chr>   <lgl>        
 1 DEPARTMENT OF PHARMACY,… AMSTE…        1 NETHER… TRUE         
 2 DEPARTMENT OF BIOCHEMIS… NA            0 NA      NA           
 3 DEPARTMENT OF PATHOLOGY… NA            0 NA      NA           
 4 COLLEGE OF EDUCATION FO… BAGHD…        1 IRAQ    FALSE        
 5 DEPARTMENT OF CLINICAL … BEIJI…        1 CHINA   TRUE         
 6 LABORATORY OF MOLECULAR… NA            0 NA      NA           
 7 BERLIN INSTITUTE OF HEA… BERLIN        1 GERMANY FALSE        
 8 INSTITUTE OF LABORATORY… NA            0 NA      NA           
 9 DEPARTMENT OF CLINICAL … BANGK…        1 THAILA… TRUE         
10 DEPARTMENT OF BIOLOGY, … NA            0 NA      NA           
11 DEPARTMENT OF MOLECULAR… NA            0 NA      NA           
12 LABORATORY OF CARDIOVAS… BEIJI…        1 CHINA   TRUE   

然后您可以仔细检查 1 个 nmatchescountry_match == F 的案例,当有 2 个或更多 nmatches 时,您可以保留 country_match == T 的案例。