Логика `reorder ()` в `R`? - PullRequest
       3

Логика `reorder ()` в `R`?

0 голосов
/ 22 ноября 2018

Мне трудно понять логику, стоящую за reorder().

Предположим, что Var определено следующим образом:

Var <- factor(c(0.2, 0.1, -0.1))
order(Var)

Теперь, если я хочу изменить его на c (1, 2, 3), я бы запустил следующий код, который отлично работаетхорошо.

Needed_Order <- c(1, 2, 3)
Var <- reorder(Var, Needed_Order)
order(Var)

Но это не работает, если я хочу изменить порядок Var в c (3, 1, 2)

Needed_Order <- c(3,1,2)
Var <- reorder(Var, Needed_Order)
order(Var)

Я ожидаю получить 3 1 2 каквывод order(var), но возвращает 2 3 1.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Я думаю, у @prosoitos уже есть отличный ответ.Я просто хотел проиллюстрировать, почему существует функция reorder и как она полезна.

Упорядочение групп на графике

Давайте рассмотрим классический iris набор данных

> data(iris)
> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

и предположим, что мы хотим построить значения Sepal.Width, сравнивая их по Species

boxplot(Sepal.Width ~ Species, iris)

enter image description here

, но порядок здесь по названию вида, тогда как мы думаем, что графикбудет выглядеть лучше, если мы упорядочим по средней ширине чашелистика каждого вида.И вот где reorder - быстрое и мощное решение для этого:

iris$Species <- reorder(iris$Species, iris$Sepal.Width, FUN=mean)
boxplot(Sepal.Width ~ Species, iris)

enter image description here

Здесь произошло то, что значения iris$Sepal.Width соответствуют каждому уровню в iris$Species к ним была применена функция mean, а результат был присоединен к фактору в виде атрибута scores:

> attr(iris$Species, 'scores')
    setosa versicolor  virginica
     3.428      2.770      2.974

Эти баллы затем использовались для ранжирования (в порядке возрастания) уровней вфактор и назначьте им этот порядок:

> levels(iris$Species)
[1] "versicolor" "virginica"  "setosa"

Обратите внимание, что это не меняет порядок каких-либо из данных в кадре данных, а только порядок используемых кодовв фактор.Аргумент FUN делает функцию reorder достаточно общей, так что можно упорядочить по минимальным или максимальным значениям или любую другую функцию, которую вы хотите вычислить для сгруппированных данных.

В целом, я думаю, что ключевая вещьзаключается в том, что второй аргумент в функции reorder, который считался желаемым порядком, предназначен для ввода весов или значений, связанных с каждой записью в факторе.

0 голосов
/ 22 ноября 2018

Функция lvls_reorder() из пакета tidyverse forcats делает то, что вы хотите:

Var <- factor(c(0.2, 0.1, -0.1))
Needed_Order <- c(3, 1, 2)
Var <- forcats::lvls_reorder(Var, Needed_Order)
order(Var)

Результат

[1] 3 1 2

Пояснения

Давайте используем пример с различными элементами для значений, уровней и порядковых позиций уровней, чтобы упростить визуализацию происходящего:

f <- factor(c(a = "A", b = "B", c = "C"))
f
# a b c 
# A B C 
# Levels: A B C

order(f)
# [1] 1 2 3

Сейчасдавайте использовать stats::reorder():

reorder(f, c(3, 1, 2))
# a b c 
# A B C 
# attr(,"scores")
# A B C 
# 3 1 2 
# Levels: B C A

reorder() присваивает значения 3 1 2 как "scores" attributes для уровней A B C и переупорядочивает эти уровни в соответствии с этими показателями: переупорядочивание результатов в 1 2 3 переупорядочивает уровни в B C A.

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

order(reorder(f, c(3, 1, 2)))
# [1] 2 3 1

Для сравнения,forcats::lvls_reorder() просто переупорядочивает уровни, индексируя их значениями 3 1 2 (что вы пытались сделать):

lvls_reorder(f, c(3, 1, 2))
# a b c
# A B C
# Levels: C A B

, что дает порядок:

order(lvls_reorder(f, c(3, 1, 2)))
# [1] 3 1 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...