Переименование столбцов во фрейме данных по списку соответствий

#r #dataframe #rename

Вопрос:

Я пытаюсь переименовать столбцы фрейма данных через таблицу соответствия, фрейм данных с двумя столбцами (имя до и имя после).

В моей ситуации в фрейме данных для переименования могут быть столбцы, на которые нет ссылок в моей таблице соответствия (это не проблема, они не будут переименованы), и, наоборот, таблица соответствия может содержать имена, не включенные в мой фрейм данных. Этот список может быть использован для других кадров данных.

И, по крайней мере, порядок имен может быть разным в 2 кадрах данных, это было бы слишком просто.

У меня есть решение с циклом, но попробуйте найти другое решение, без цикла.

Есть идеи ? Заранее спасибо.

Вот мой код

 
df_to_rename <- data.frame(annee = 2010:2012,
                            code_commune = 67000:67002,
                            duree_occup_ou_vacance_tranche = 1:3,
                            nb_total_logements = 100:102,
                            secret_not_in_list  = 1:3)

liste_noms_col <- data.frame(noms_origine = c("mode_occ",
                                              "code_commune",
                                              "annee",
                                              "duree_occup_ou_vacance_tranche",
                                              "nb_total_logements"),
                             noms_nouveaux = c("mode d'occupation - not included",
                                               "code INSEE commune",
                                               "Année",
                                               "durée d'occupation (ou vacance)",
                                               "Nombre de logements"))


##### Rename by loop

l_noms <- df_to_rename %>% names()

# (i_nom  <-  l_noms[1])
for(i_nom in l_noms) {
  nom_a_changer <-
    liste_noms_col[liste_noms_col$noms_origine == i_nom, "noms_nouveaux"]
  # message(i_nom," -> ",nom_a_changer)
  
  if(length(nom_a_changer)>0) {
    df_to_rename <- df_to_rename %>%
      rename({{nom_a_changer}} := {{i_nom}})
    message(i_nom," -> ",nom_a_changer)
  }
}
df_to_rename %>% names()
 

Ответ №1:

Превратитесь liste_noms_col в список с deframe , отфильтруйте интересующие имена и rename() :

 library(dplyr)

liste_noms_col <- deframe(liste_noms_col[, 2:1])
liste_noms_col <- liste_noms_col[liste_noms_col %in% names(df_to_rename)]

rename(df_to_rename, !!! liste_noms_col)
 

Проверка замены triple-bang ( !!! ) «без кавычек» :

 expr(
  rename(df_to_rename, !!! liste_noms_col)
)

#> rename(df_to_rename, `code INSEE commune` = "code_commune", 
#>     Année = "annee", `durée d'occupation (ou vacance)` = "duree_occup_ou_vacance_tranche", 
#>     `Nombre de logements` = "nb_total_logements")
 

Ответ №2:

Используйте match и получите новые имена столбцов фрейма данных, в котором он присутствует liste_noms_col . Для имен столбцов , в которых их нет liste_noms_col , сохраните исходные столбцы в том виде, в каком они есть.

 cols <- liste_noms_col$noms_nouveaux[match(names(df_to_rename), liste_noms_col$noms_origine)]
cols[is.na(cols)] <- names(df_to_rename)[is.na(cols)]
names(df_to_rename) <- cols
df_to_rename

#  Année code INSEE commune durée d'occupation (ou vacance) Nombre de logements secret_not_in_list
#1  2010              67000                               1                 100                  1
#2  2011              67001                               2                 101                  2
#3  2012              67002                               3                 102                  3
 

С помощью dplyr :

 library(dplyr)

df_to_rename %>%
  rename_with(~coalesce(liste_noms_col$noms_nouveaux[match(., liste_noms_col$noms_origine)], .))