Измените уровни коэффициентов в R, используя переменную КАК для имени фактора, ТАК И для порядка уровней во фрейме данных

#r

#r

Вопрос:

У меня большой фрейм данных 1 с большим количеством столбцов, которые являются факторами. Я хочу изменить порядок уровней факторов для каждого фактора.

У меня есть фрейм данных поиска 2 для правильных порядков уровня факторов. Это означает, что я могу ссылаться на фрейм данных поиска, используя переменную для фактора. Я могу захватить порядок и поместить его в другую переменную. Пока все хорошо.

Упрощенный пример:

 d = tibble(
  size = c('small','small','big', NA)
)
d$size = as.factor(d$size)

levels(d$size) # Not what I want.

proper.order = c('small', 'big') # this comes from somewhere else
  

Я могу использовать proper.order для изменения одного столбца в d.

 d$size = factor(d$size, levels = proper.order)

levels(d$size) # What I want.
  

Я хочу обратиться к имени столбца ( size ) с помощью переменной.

Это не работает:

 my.column = 'size'

d[names(d) == my.column] = factor(d[names(d) == my.column], levels = proper.order, exclude = NULL)


levels(d$size) # What I want.
d # Not what I want.

  

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

Я подозреваю d[names(d) == my.column] , что это связано с тем, что это ошибка, а не фактор. Но тогда почему уровни факторов меняются? И как я могу проникнуть в tibble и захватить фактор?

Ответ №1:

Для нескольких столбцов мы можем указать в mutate_at

 library(dplyr)
d %>% 
   mutate_at(vars(my.column), 
        list(~ factor(., levels = proper.order, exclude = NULL)))
  

Или с fct_relevel помощью from forcats

 library(forcats)
d %>%
    mutate_at(vars(my.column), list(~ fct_relevel(., proper.order))) 
  

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

1. Спасибо. list не обязательно, если это одна функция, верно? итак, для mutate_at это тоже d %>% mutate_at(vars(my.column), ~ factor(., levels = proper.order, exclude = NULL)) сработает?

2. @petyar Это тоже работает, но рекомендуется обернуть с list