我很难理解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
。
答案 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)
,但是这里的顺序是按物种名称进行的,而我们认为,如果按照每种物种的平均萼片宽度进行排序,该图看起来会更好。这就是reorder
是快速,强大的解决方案:
iris$Species <- reorder(iris$Species, iris$Sepal.Width, FUN=mean)
boxplot(Sepal.Width ~ Species, iris)
这里发生的是,与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