Как определить все названия стран, упомянутые в строке, и соответственно разбить их?

У меня есть строка, содержащая названия стран и других регионов. Меня интересуют только названия стран, и в идеале я хотел бы добавить несколько столбцов, каждый из которых содержит название страны, указанное в строке. Вот примерный код того, как настроен фрейм данных:

df <- data.frame(id = c(1,2,3),
                 country = c("Cote d'Ivoire Africa Developing Economies West Africa",
                              "South Africa United Kingdom Africa BRICS Countries",
                             "Myanmar Gambia Bangladesh Netherlands Africa Asia"))

Если я разделю строку только на пробел, те страны, которые содержат пробел, будут потеряны (например, Великобритания). Посмотреть здесь:

df2 <- separate(df, country, paste0("C",3:8), sep=" ") 

Поэтому я попытался найти названия стран, используя набор данных world.cities. Однако это только кажется, что строка перебирается до тех пор, пока не появится имя, отличное от страны. Посмотреть здесь:

library(maps)
library(stringr)
all_countries <- str_c(unique(world.cities$country.etc), collapse = "|")
df$c1 <- sapply(str_extract_all(df$country, all_countries), toString)

Мне интересно, можно ли использовать пробел в качестве разделителя, но определять исключения (например, Соединенное Королевство). Очевидно, это может потребовать некоторой ручной работы, но для меня это наиболее реальное решение. Кто-нибудь знает, как определять такие исключения? Я, конечно, также открыт и благодарен за любые другие решения.

ОБНОВЛЕНИЕ:

Я нашел другое решение, используя пакет countrycode:

library(countrycode)
countries <- data.frame(countryname_dict)
countries$continent <- countrycode(sourcevar = countries[["country.name.en"]],
                                   origin = "country.name.en",
                                   destination = "continent")

africa <- countries[ which(countries$continent=='Africa'), ]

library(stringr)
pat <- paste0("\\b", paste(africa$country.name.en , collapse="\\b|\\b"), "\\b")
df$country_list <- str_extract_all(df$country, regex(pat, ignore_case = TRUE))

person Lisa    schedule 20.11.2020    source источник
comment
Это возможно, но таких стран может быть несколько.   -  person akrun    schedule 21.11.2020
comment
Привет, спасибо за быстрый ответ. Не могли бы вы указать, как это возможно? Спасибо!   -  person Lisa    schedule 21.11.2020
comment
Зависит от того, есть ли у вас список названий стран с несколькими словами   -  person akrun    schedule 21.11.2020
comment
Это похоже на пример в начале моего вопроса; например ЮАР Великобритания Африка Страны БРИКС   -  person Lisa    schedule 21.11.2020
comment
А что насчет Cote d'Ivoire? Это страна   -  person akrun    schedule 21.11.2020
comment
@akrun да, Cote d'Ivoire это страна в Африке. Западная Африка, если быть точным.   -  person Onyambu    schedule 21.11.2020


Ответы (1)


Вы могли сделать:

library(stringi)
vec <- stri_trans_general(countrycode::codelist$country.name.en, id = "Latin-ASCII")
stri_extract_all(df$country,regex = sprintf(r"(\b(%s)\b)",stri_c(vec,collapse = "|")))
[[1]]
[1] "Cote d'Ivoire"

[[2]]
[1] "South Africa"   "United Kingdom"

[[3]]
[1] "Gambia"      "Bangladesh"  "Netherlands"
person Onyambu    schedule 20.11.2020
comment
Большое спасибо. Это хорошо работает. Одно небольшое примечание. = Отсутствует. Должно быть: stri_extract_all(df$country,regex = sprintf(r="(\b(%s)\b)",stri_c(vec,collapse = "|"))) - person Lisa; 21.11.2020
comment
Я только что обнаружил в вашем решении одну проблему, которую мне не удалось исправить. В текстовых строках есть как Нигерия, так и Нигер, и все строки Нигерии заканчиваются как Нигер (похоже, извлечено первое возможное совпадение). Любые идеи, как это исправить? - person Lisa; 23.11.2020
comment
@Lisa, вы добавили еще =, ВЫ ДОЛЖНЫ СДЕЛАТЬ ТОЧНО, КАК ОПУБЛИКОВАНО ВЫШЕ. нет пропавших без вести =. Примите к сведению это - person Onyambu; 23.11.2020
comment
Спасибо за ваш ответ @Onyambu, если я это сделаю, я получаю следующее сообщение об ошибке в R: Ошибка: неожиданная строковая константа в stri_extract_all (df $ country, regex = sprintf (r (\ b (% s) \ b). Я нашел решение, используя пакет countrycode (см. Обновленный вопрос) - person Lisa; 23.11.2020
comment
@Lisa, похоже, вы используете старую версию R. Вместо этого замените ее на sprintf('\\b(%s)\\b',.......). Точки означают поддерживать все остальное - person Onyambu; 23.11.2020
comment
Спасибо большое! - person Lisa; 23.11.2020