Перезапись выходных данных функции, влияющей на несколько столбцов, во фрейм данных

#r #function

#r #функция

Вопрос:

У меня есть большой фрейм данных (travel), содержащий множество отдельных историй путешествий. В столбце travel $ Travel 1 Destination мне нужны только данные о стране, но во многих записях указаны регион, город или другие данные.

Я пытался написать функцию (city_replace_with_country) с 2 аргументами:

  • city_name: название города, которое уже есть в столбце travel $`Пункт назначения Travel 1′
  • имя_страны_: название страны, которой оно должно быть

Я хотел бы, чтобы моя функция обнаружила эти ошибки во фрейме данных, вставила их в другой уже существующий столбец (travel $ regions_visited) и заменила название города / региона в travel $ `Пункт назначения Travel 1′ на правильное название страны.

Этот код отлично работает для отдельных примеров, например, в Бангалоре и Индии

 for (i in 1:nrow(travel) ) {
  if(grepl("bangalore", travel$`Travel 1 Destination`[i], ignore.case = TRUE)){
  travel$regions_visited[i] <- paste(travel$regions_visited[i], "Bangalore", sep = " ")
  travel$`Travel 1 Destination`[i] <- gsub("bangalore", "india", travel$`Travel 1 Destination`[i], ignore.case = TRUE, perl = TRUE)
  }}

  

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

 city_replace_with_country <- function(city_name, country_name) {
    for (i in 1:nrow(travel)) {
    if(grepl(city_name, travel$`Travel 1 Destination`[i], ignore.case = TRUE)){
      travel$regions_visited[i] <- paste(travel$regions_visited[i], city_name, sep = " ")
      travel$`Travel 1 Destination`[i] <- gsub(city_name, country_name, travel$`Travel 1 Destination`[i], ignore.case = TRUE, perl = TRUE)
    }}}
  

Когда я пытаюсь использовать эту функцию следующим образом:

 city_replace_with_country("bangalore", "india")
  

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

 travel <- city_replace_with_country("bangalore", "india")
  

или

 travel$`Travel 1 Destination` <- city_replace_with_country("bangalore", "india")
  

Возвращает нулевое значение.

Любые предложения относительно того, как заставить это работать, были бы высоко оценены. Большое спасибо.

Вот несколько примеров данных. В этом случае, например, я хотел бы изменить Боготу на Колумбию:

 travel_example <- structure(list(X1 = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
13, 14, 15, 16, 17, 18, 19, 20, 21), `Travel 1 Dates` = c("03/09/18 to 02/10/18", 
NA, "15/08/18 - 24/08/18", "13/09/2018 to 19/09/2018", "15/07- 14/08", 
"21/9/18-29/9/18", "10/09/18-3/10/18", "28/5/18-31/7/18", "1/9/18-16/9/18", 
NA, NA, NA, "15/07/18-03/10/18", "15/09/18-30/09/18", "18/09/18-05/10/18", 
"7/9/18-23/9/18", "14/8/18-11/9/18", "25/7/18-13/8/18", "24/9/18-30/9/18", 
NA, "18/9/18-2/10/18"), `Travel 1 Destination` = c("Colombia", 
"salvador, Bogata, Honduras", "China,Cambodia", "Lagos, Nigeria", 
"Uganda", "Indonesia", "Kenya", "Dubai, Japan", "Sri Lanka", 
"Jakarta,Indonesia", "South Africa, Mozambique, Ethiopia", NA, 
"Ukraine, Slovakia, India", "Tanzania", "Ghana", "Sri Lanka", 
"Angola", "Tajikistan , Afghanistan", "Morocco", NA, "Tanzania"
), regions_visited = c("character(0)", "character(0)", "character(0)", 
"character(0)", "character(0)", "character(0)", "Nairobi", "character(0)", 
"character(0)", "character(0)", "character(0)", "character(0)", 
"character(0)", "character(0)", "character(0)", "character(0)", 
"Luanda only", "c("south", "north", "very rural")", "character(0)", 
"character(0)", "character(0)")), class = c("spec_tbl_df", "tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -21L), spec = structure(list(
    cols = list(X1 = structure(list(), class = c("collector_double", 
    "collector")), `Travel 1 Dates` = structure(list(), class = c("collector_character", 
    "collector")), `Travel 1 Destination` = structure(list(), class = c("collector_character", 
    "collector")), regions_visited = structure(list(), class = c("collector_character", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))
  

Комментарии:

1. Пожалуйста, поделитесь примером фрейма данных с dput

2. Спасибо. Добавлен пример.

3. Извините, только что исправил выходные данные dput (первоначально проанализированные с помощью read.csv, когда должно было быть read_csv).

Ответ №1:

В вашем случае вы могли бы просто извлечь последнее слово после запятой с помощью regex и получить все названия стран, как показано ниже:

 travel_example$`Travel 1 Destination` <- sub('.*,\s*', '', travel_example$`Travel 1 Destination`)
travel_example$`Travel 1 Destination`
 [1] "Colombia"    "Honduras"    "Cambodia"    "Nigeria"     "Uganda"     
 [6] "Indonesia"   "Kenya"       "Japan"       "Sri Lanka"   "Indonesia"  
[11] "Ethiopia"    NA            "India"       "Tanzania"    "Ghana"      
[16] "Sri Lanka"   "Angola"      "Afghanistan" "Morocco"     NA           
[21] "Tanzania"