Переупорядочить уровни фактора без изменения порядка значений

У меня есть кадр данных с некоторыми численными переменными и некоторыми категориальными factor переменными. Порядок уровней для этих факторов не так, как я хочу, чтобы они были.

 numbers <- 1:4 letters <- factor(c("a", "b", "c", "d")) df <- data.frame(numbers, letters) df # numbers letters # 1 1 a # 2 2 b # 3 3 c # 4 4 d 

Если я изменю порядок уровней, буквы больше не будут с их соответствующими номерами (мои данные – полная глупость с этой точки).

 levels(df$letters) <- c("d", "c", "b", "a") df # numbers letters # 1 1 d # 2 2 c # 3 3 b # 4 4 a 

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

    Используйте аргумент levels factor :

     df <- data.frame(f = 1:4, g = letters[1:4]) df # fg # 1 1 a # 2 2 b # 3 3 c # 4 4 d levels(df$g) # [1] "a" "b" "c" "d" df$g <- factor(df$g, levels = letters[4:1]) # levels(df$g) # [1] "d" "c" "b" "a" df # fg # 1 1 a # 2 2 b # 3 3 c # 4 4 d 

    еще несколько, только для записи

     ## reorder is a base function df$letters <- reorder(df$letters, new.order=letters[4:1]) library(gdata) df$letters <- reorder.factor(df$letters, letters[4:1]) 

    Вы также можете найти полезные функции Releasevel и comb_factor .

    так что вы хотите, в R lexicon, это изменить только метки для данной фактор-переменной (т. е. оставить данные, а также уровни факторов неизменными).

     df$letters = factor(df$letters, labels=c("d", "c", "b", "a")) 

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

    правила просты:

    • метки сопоставляются с уровнями по значению индекса (т. е. значение на уровнях [2] дается меткой, меткой [2]);
    • уровни факторов могут быть заданы явно, передавая их через аргумент уровней ; или
    • если для аргумента уровней не задано значение, используется значение по умолчанию, которое является результатом вызова, уникальным для передаваемого в векторе данных (для аргумента данных );
    • ярлыки могут быть заданы явно через аргумент меток; или
    • если для аргумента меток не задано значение, используется значение по умолчанию, которое является только вектором уровней

    Работа с факторами в R – довольно своеобразная работа, я должен признать … При переупорядочивании уровней факторов вы не переупорядочиваете базовые численные значения. Вот небольшая демонстрация:

     > numbers = 1:4 > letters = factor(letters[1:4]) > dtf <- data.frame(numbers, letters) > dtf numbers letters 1 1 a 2 2 b 3 3 c 4 4 d > sapply(dtf, class) numbers letters "integer" "factor" 

    Теперь, если вы преобразуете этот коэффициент в числовой, вы получите:

     # return underlying numerical values 1> with(dtf, as.numeric(letters)) [1] 1 2 3 4 # change levels 1> levels(dtf$letters) <- letters[4:1] 1> dtf numbers letters 1 1 d 2 2 c 3 3 b 4 4 a # return numerical values once again 1> with(dtf, as.numeric(letters)) [1] 1 2 3 4 

    Как вы можете видеть … путем изменения уровней, вы меняете только уровни (кто скажет, а?), А не числовые значения! Но, когда вы используете factor функцию, как предположил @Jonathan Chang, происходит что-то другое: вы сами меняете числовые значения.

    Вы снова получаете ошибку, потому что вы делаете levels а затем пытаетесь устранить ее с помощью factor . Не делай этого !!! Не используйте levels иначе вы все испортите (если вы точно не знаете, что делаете).

    Предложение lil ‘: избегать присвоения имен вашим объектам с таким же именем, как объекты R ( df – функция плотности для распределения F, letters строчные буквы алфавита). В этом конкретном случае ваш код не будет ошибочным, но иногда он может быть … но это может создать путаницу, и мы этого не хотим, не так ли?!? знак равно

    Вместо этого используйте что-то вроде этого (я снова начну с начала):

     > dtf <- data.frame(f = 1:4, g = factor(letters[1:4])) > dtf fg 1 1 a 2 2 b 3 3 c 4 4 d > with(dtf, as.numeric(g)) [1] 1 2 3 4 > dtf$g <- factor(dtf$g, levels = letters[4:1]) > dtf fg 1 1 a 2 2 b 3 3 c 4 4 d > with(dtf, as.numeric(g)) [1] 4 3 2 1 

    Обратите внимание, что вы также можете назвать data.frame с df и letters вместо g , и результат будет в порядке. На самом деле этот код идентичен тому, который вы опубликовали, только имена изменены. Этот factor(dtf$letter, levels = letters[4:1]) не будет вызывать ошибку, но это может быть смешано!

    Внимательно прочитайте руководство ?factor В чем разница между factor(g, levels = letters[4:1]) и factor(g, labels = letters[4:1]) ? Что похоже в levels(g) <- letters[4:1] и g <- factor(g, labels = letters[4:1]) ?

    Вы можете установить синтаксис ggplot, чтобы мы могли помочь вам в этом!

    Ура !!!

    Редактировать:

    ggplot2 действительно требует изменения обоих уровней и значений? Хм ... Я выкопаю этот ...

    Поскольку этот вопрос был в последний раз активным, Хэдли выпустил свой новый пакет forcats для манипулирования факторами, и я forcats его forcats полезным. Примеры из фрейма данных OP:

     levels(df$letters) # [1] "a" "b" "c" "d" 

    Чтобы изменить уровни:

     library(forcats) fct_rev(df$letters) %>% levels # [1] "d" "c" "b" "a" 

    Чтобы добавить дополнительные уровни:

     fct_expand(df$letters, "e") %>% levels # [1] "a" "b" "c" "d" "e" 

    И еще много полезных fct_xxx() .

    Я хочу добавить еще один случай, когда уровни могут быть строками, несущими числа вместе с некоторыми специальными символами: например, ниже

     df <- data.frame(x = c("15-25", "0-4", "5-10", "11-14", "100+")) 

    Уровни по умолчанию x :

     df$x # [1] 15-25 0-4 5-10 11-14 100+ # Levels: 0-4 100+ 11-14 15-25 5-10 

    Здесь, если мы хотим изменить порядок уровней факторов в соответствии с числовым значением, без явного написания уровней, что мы можем сделать, это

     library(gtools) df$x <- factor(df$x, levels = mixedsort(df$x)) df$x # [1] 15-25 0-4 5-10 11-14 100+ # Levels: 0-4 5-10 11-14 15-25 100+ as.numeric(df$x) # [1] 4 1 2 3 5 

    Надеюсь, это можно считать полезной информацией для будущих читателей.

    Вот моя функция для изменения коэффициентов заданного кадра данных:

     reorderFactors <- function(df, column = "my_column_name", desired_level_order = c("fac1", "fac2", "fac3")) { x = df[[column]] lvls_src = levels(x) idxs_target <- vector(mode="numeric", length=0) for (target in desired_level_order) { idxs_target <- c(idxs_target, which(lvls_src == target)) } x_new <- factor(x,levels(x)[idxs_target]) df[[column]] <- x_new return (df) } 

    Использование: reorderFactors(df, "my_col", desired_level_order = c("how","I","want"))

    Interesting Posts

    Построить и установить unsigned apk на устройстве без сервера разработки?

    Как легко и непрерывно контролировать температуру процессора, используя только «датчики» (без виджета gui)?

    Объявление переменной внутри или вне цикла foreach: что быстрее / лучше?

    Ошибка MySQL 1093 – Невозможно указать целевую таблицу для обновления в предложении FROM

    Как resize разделенных экранов emacs?

    Как вернуть отклоненное приглашение

    Изображение в Google Картах?

    C / C ++: переключатель для нецелых чисел

    как использовать представления в первой структуре сущности кода

    Арифметические операции с HH: MM: SS раз в пакетном файле

    Неисправность Jar! Исправьте свои зависимости

    Может кто-нибудь, пожалуйста, объясните async / wait?

    Что я должен использовать: «Write-Host», «Write-Output» или « :: WriteLine»?

    Как удалить определенный элемент из JSONArray?

    Отображения рабочего пространства разработчика Chrome.

    Давайте будем гением компьютера.