переименование всех столбцов фрейма данных с помощью stringr и dplyr

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

Вот полностью воспроизводимый код:

library(dplyr)
library(stringr)
library(tibble)
library(rlang)

# dataframe
x <-
  tibble::as.tibble(cbind(
    Grace_neu_wrong = c(1:4),
    Grace_acc_wrong = c(1:4),
    Grace_att_wrong = c(1:4),
    Grace_int_wrong = c(1:4)
  ))

# defining custom function to rename the entire dataframe in a certain way
string_conversion <- function(df, ...) {

  # preparing the dataframe
  df <- dplyr::select(.data = df,
                      !!rlang::quo(...))

  # custom function to split the name of each column in a certain way
  splitfn <- function(x) {
    x <- as.character(x)
    split <- stringr::str_split(string = x, pattern = "_")[[1]]
    paste(split[2], split[3], '_', split[1], sep = '')
  }

  # applying the splitfn function to each column name and outputting the data frame
  df_new <- df %>%
    dplyr::select_all(.funs = colnames) %>%
    dplyr::mutate_all(.funs = splitfn)

  return(df_new)

}

# the output I get
string_conversion(df = x, names(x))
#> # A tibble: 4 x 4
#>   Grace_neu_wrong Grace_acc_wrong Grace_att_wrong Grace_int_wrong
#>   <chr>           <chr>           <chr>           <chr>          
#> 1 NANA_1          NANA_1          NANA_1          NANA_1         
#> 2 NANA_1          NANA_1          NANA_1          NANA_1         
#> 3 NANA_1          NANA_1          NANA_1          NANA_1         
#> 4 NANA_1          NANA_1          NANA_1          NANA_1

# the output I desire
tibble::as.tibble(cbind(
  neuwrong_Grace = c(1:4),
  accwrong_Grace = c(1:4),
  attwrong_Grace = c(1:4),
  intwrong_Grace = c(1:4)
))
#> # A tibble: 4 x 4
#>   neuwrong_Grace accwrong_Grace attwrong_Grace intwrong_Grace
#>            <int>          <int>          <int>          <int>
#> 1              1              1              1              1
#> 2              2              2              2              2
#> 3              3              3              3              3
#> 4              4              4              4              4

Создано 8 февраля 2018 г. пакетом REPEX (v0.1.1.9000).


person Indrajeet Patil    schedule 08.02.2018    source источник


Ответы (1)


Вы можете сделать это в одной строке без использования функции mutate, которая должна относиться к значениям столбцов, а не к именам столбцов. Вместо этого сделайте следующее, используя stringr::str_replace и регулярные выражения.

  1. Шаблон "(.*)_(.*)_(.*)" представляет собой три группы символов, разделенных подчеркиванием.
  2. Мы просто выполняем замену "\\2\\3_\\1", то есть группу 2, затем группу 3, затем знак подчеркивания, затем группу 1, что дает нам желаемый результат.

Следовательно, код состоит всего из одной строки:

names(x) <- str_replace(names(x), "(.*)_(.*)_(.*)", "\\2\\3_\\1")
print(x)
# A tibble: 4 x 4
  neuwrong_Grace accwrong_Grace attwrong_Grace intwrong_Grace
           <int>          <int>          <int>          <int>
1              1              1              1              1
2              2              2              2              2
3              3              3              3              3
4              4              4              4              4
person Calum You    schedule 08.02.2018
comment
Большое тебе спасибо. Очень элегантное решение. - person Indrajeet Patil; 09.02.2018