Подтвердить что ты не робот

Изменение уровней факторов с помощью dplyr mutate

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

library("dplyr")
dat <- data.frame(x = factor("A"), y = 1)
mutate(dat,levels(x) = "B")

Я получаю:

Error: Unexpected '=' in "mutate(dat,levels(x) ="

Почему это не работает? Как изменить уровни факторов с мутацией?

4b9b3361

Ответ 1

Я не совсем уверен, что правильно понял ваш вопрос, но если вы хотите изменить уровни факторов cyl на mutate(), вы могли бы сделать:

df <- mtcars %>% mutate(cyl = factor(cyl, levels = c(4, 6, 8)))

Вы получите:

#> str(df$cyl)
# Factor w/ 3 levels "4","6","8": 2 2 1 2 3 2 3 1 1 2 ...

Ответ 2

Возможно, вы ищете эту функцию plyr:: revalue:

mutate(dat, x = revalue(x, c("A" = "B")))

Вы также можете увидеть plyr:: mapvalues.

Ответ 3

С новым пакетом forcats by @hadley (объявление в блоге RStudio), это тоже легко.

mutate (dat, x = fct_recode (x, "B" = "A" ))

forcats также является частью tidyverse (объявление), который plyr не соответствует @hadley (см. первый комментарий в объявлении).

Ответ 4

Вы можете использовать функцию recode от dplyr.

df <- iris %>%
     mutate(Species = recode(Species, setosa = "SETOSA",
         versicolor = "VERSICOLOR",
         virginica = "VIRGINICA"
     )
)

Ответ 5

Не могу комментировать, потому что у меня недостаточно очков репутации, но перекодировка работает только с вектором, поэтому приведенный выше код в ответе @Stefano должен быть

df <- iris %>%
  mutate(Species = recode(Species, 
     setosa = "SETOSA",
     versicolor = "VERSICOLOR",
     virginica = "VIRGINICA")
  )

Ответ 6

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

Поверните cyl в коэффициент (требуемые уровни не нужны, поскольку они закодированы в алфавитно-цифровом порядке):

    mtcars2 <- mtcars %>% mutate(cyl = factor(cyl, levels = c(4, 6, 8))) 
    mtcars2$cyl[1:5]
    #[1] 6 6 4 6 8
    #Levels: 4 6 8

Измените порядок уровней (но не сами метки: cyl все равно один и тот же столбец)

    mtcars3 <- mtcars2 %>% mutate(cyl = factor(cyl, levels = c(8, 6, 4))) 
    mtcars3$cyl[1:5]
    #[1] 6 6 4 6 8
    #Levels: 8 6 4
    all(mtcars3$cyl==mtcars2$cyl)
    #[1] TRUE

Назначьте новые ярлыки cyl. Порядок меток: c (8, 6, 4), поэтому мы указываем новые метки следующим образом:

    mtcars4 <- mtcars3 %>% mutate(cyl = factor(cyl, labels = c("new_value_for_8", 
                                                               "new_value_for_6", 
                                                               "new_value_for_4" )))
    mtcars4$cyl[1:5]
    #[1] new_value_for_6 new_value_for_6 new_value_for_4 new_value_for_6 new_value_for_8
    #Levels: new_value_for_8 new_value_for_6 new_value_for_4

Обратите внимание, что этот столбец отличается от наших первых столбцов:

    all(as.character(mtcars4$cyl)!=mtcars3$cyl) 
    #[1] TRUE 
    #Note: TRUE here indicates that all values are unequal because I used != instead of ==
    #as.character() was required as the levels were numeric and thus not comparable to a character vector

Подробнее:

Если бы мы изменили уровни cyl, используя mtcars2 вместо mtcars3, нам нужно было бы указать метки по-разному, чтобы получить тот же результат. Порядок меток для mtcars2 был: c (4, 6, 8), поэтому мы указываем новые метки следующим образом:

    #change labels of mtcars2 (order used to be: c(4, 6, 8)
    mtcars5 <- mtcars2 %>% mutate(cyl = factor(cyl, labels = c("new_value_for_4", 
                                                               "new_value_for_6", 
                                                               "new_value_for_8" )))

В отличие от mtcars3$cyl и mtcars4$cyl, метки mtcars4$cyl и mtcars5$cyl, таким образом, идентичны, хотя их уровни имеют другой порядок.

    mtcars4$cyl[1:5]
    #[1] new_value_for_6 new_value_for_6 new_value_for_4 new_value_for_6 new_value_for_8
    #Levels: new_value_for_8 new_value_for_6 new_value_for_4

    mtcars5$cyl[1:5]
    #[1] new_value_for_6 new_value_for_6 new_value_for_4 new_value_for_6 new_value_for_8
    #Levels: new_value_for_4 new_value_for_6 new_value_for_8

    all(mtcars4$cyl==mtcars5$cyl)
    #[1] TRUE

    levels(mtcars4$cyl) == levels(mtcars5$cyl)
    #1] FALSE  TRUE FALSE