R中的reorder()背后的逻辑?

时间:2018-11-22 03:15:14

标签: r

我很难理解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 :(得分:3)

我认为@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,结果附加到因子上,成为{{1} }属性:

scores

然后使用这些分数对因素中的水平进行排名(按升序排列),并按以下顺序分配它们:

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

请注意,这不会更改数据框中任何 data 的顺序,而只会更改因子中使用的代码的顺序。 > levels(iris$Species) [1] "versicolor" "virginica" "setosa" 参数使FUN函数非常通用,因此可以按min或max或要对分组数据计算的任何函数进行排序。

总体而言,我认为关键是reorder函数中的第二个参数被认为是期望的顺序,而是用于输入与因子中每个条目相关的权重或值。 / p>

答案 1 :(得分:2)

tidyverse包forcats中的函数lvls_reorder()完成了您想要的操作:

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