R — мутировать с помощью регулярного выражения в цикле

#r #dataframe #dplyr #tidyverse #data-cleaning

#r #dataframe #dplyr #tidyverse #очистка данных

Вопрос:

У меня есть фрейм данных, в котором каждый столбец состоит из числа, за которым следует текст, например, 533 234r / r.

Следующий код для удаления текста работает хорошо:

   my_data <- my_data %>%
    mutate(column1 = str_extract(column1, '. ?(?=[a-z])'))
 

Я хотел бы сделать это для нескольких столбцов:

 col_names <- names(my_data)
for (i in 1:length(col_names)) {
  my_data <- my_data%>%
    mutate(col_names[i] = str_extract(col_names[i], '. ?(?=[a-z])'))
}
 

Но он возвращает ошибку:

 Error: unexpected '=' in:
"  my_data <- my_data %>%
    mutate(col_names[i] ="
 

Я думаю, что mutate_all() также не будет работать, bcos str_extract() требует имя столбца в качестве аргумента.

Ответ №1:

Если мы используем строки, тогда преобразуйте в sym bol и вычисляйте ( !! ), пока мы выполняем присваивание с помощью ( := )

 library(dplyr)
library(stringr)
col_names <- names(my_data)
for (i in seq_along(col_names)) {
  my_data <- my_data   %>%
          mutate(!! col_names[i] := 
            str_extract(!!rlang::sym(col_names[i]), '. ?(?=[a-z])'))
       }
 

В tidyverse , мы могли бы сделать это с across помощью вместо цикла с for циклом ( dplyr версия >= 1.0 )

 my_data <- my_data %>%
      mutate(across(everything(), ~ str_extract(., '. ?(?=[a-z])')))
 

Если dplyr версия старая, используйте mutate_all

 my_data <- my_data %>%
          mutate_all(~ str_extract(., '. ?(?=[a-z])'))