引子
最近在整理forcats
工具包中的函数,发现该包只有fct_reorder2()
函数的功能不太容易理解,所以单独写一篇推文来介绍它。
根据上篇提到的函数分类,它可以归为「调整类别顺序的函数」,与它类似的还有一个fct_reorder()
函数,但是功能要好理解得多。
作者对这两个函数的介绍可能会让很多读者觉得一头雾水:
「学堂君译文」:根据其他变量对因子类别重排序。当因子变量映射到位置时,fct_reorder()
函数在一维展示中非常有用;而当因子变量映射的是非位置属性时,fct_reorder2()
函数可用于二维展示;
「作者原文」:Reorder factor levels by sorting along another variable. fct_reorder()
is useful for 1d displays where the factor is mapped to position; fct_reorder2()
for 2d displays where the factor is mapped to a non-position aesthetic.
这段话之所以不太容易理解,是因为你以为它只是一个数据处理函数,但其实它主要用处却在可视化方面。英语原文中也出现了ggplot2绘图系统的术语——map和aesthetic。
fct_reorder()
函数
两个函数的语法结构如下:
fct_reorder(.f, .x, .fun = median, ..., .desc = FALSE)
fct_reorder2(.f, .x, .y, .fun = last2, ..., .desc = TRUE)
简而言之,fct_reorder()
就是根据另外「一个」变量(即参数.x
)的统计特征(由参数.fun
指定,默认为中位数)对因子变量(即参数.f
)进行重排序,默认为升序(即.desc = FALSE
)。
示例数据:
library(forcats)
f <- mtcars[, c("gear", "mpg", "qsec")]
f$gear <- factor(f$gear)
head(f)
## gear mpg qsec
## Mazda RX4 4 21.0 16.46
## Mazda RX4 Wag 4 21.0 17.02
## Datsun 710 4 22.8 18.61
## Hornet 4 Drive 3 21.4 19.44
## Hornet Sportabout 3 18.7 17.02
## Valiant 3 18.1 20.22
f$gear
## [1] 4 4 4 3 3 3 3 4 4 4 4 3 3 3 3 3 3 4 4 4 3 3 3 3 3 4 5 5 5 5 5 4
## Levels: 3 4 5
根据mpg
的平均值对gear
的类别进行升序排列:
aggregate(mpg ~ gear, data = f, FUN = mean)
## gear mpg
## 1 3 16.10667
## 2 4 24.53333
## 3 5 21.38000
fct_reorder(f$gear, f$mpg, .fun = mean, .desc = F)
## [1] 4 4 4 3 3 3 3 4 4 4 4 3 3 3 3 3 3 4 4 4 3 3 3 3 3 4 5 5 5 5 5 4
## Levels: 3 5 4
fct_reorder2()
函数
这个函数的参数从表面上看与fct_reorder()
函数有两个明显的区别:
其实,还有一个差别在同名参数.fun
上:fct_reorder()
函数要求.fun
对应的函数只需要一个向量参数;而fct_reorder2()
函数则要求有两个向量参数,其中第一个参数由.x
映射,第二个参数由.y
映射,即fun(.x, .y)
。
因此,最常见的用于描述统计特征的mean()
函数就不能用在fct_reorder2()
的参数赋值上。
fct_reorder2(f$gear, f$mpg, f$qsec, .fun = mean)
# Error in mean.default(.x[i], .y[i], ...) : 'trim'必需是长度必需为一的数值
作者专门为该函数的.fun
参数设计了两个辅助函数:
## last2为默认选项
fct_reorder2(f$gear, f$mpg, f$qsec)
## [1] 4 4 4 3 3 3 3 4 4 4 4 3 3 3 3 3 3 4 4 4 3 3 3 3 3 4 5 5 5 5 5 4
## Levels: 3 4 5
## .fun = first2
fct_reorder2(f$gear, f$mpg, f$qsec, .fun = first2)
## [1] 4 4 4 3 3 3 3 4 4 4 4 3 3 3 3 3 3 4 4 4 3 3 3 3 3 4 5 5 5 5 5 4
## Levels: 4 3 5
在可视化中的应用
作者为fct_reorder2()
函数举了如下一个示例用法。
set.seed(123)
chks <- subset(ChickWeight, as.integer(Chick) < 10)
chks <- transform(chks, Chick = fct_shuffle(Chick))
library(ggplot2)
ggplot(chks, aes(Time, weight, colour = Chick)) +
geom_point() +
geom_line()
# Note that lines match order in legend
ggplot(chks, aes(Time, weight, colour = fct_reorder2(Chick, Time, weight))) +
geom_point() +
geom_line() +
labs(colour = "Chick")
<<< 左右滑动见更多 >>>
从语句上看,第二幅图代码中ggplot()
函数的colour
参数使用了fct_reorder2()
函数进行重排序,.x
和.y
参数分别对应于横、纵坐标轴的变量。从可视化效果上看,第二幅图的图例线条顺序与图中线条的高低顺序是一一对应的。
原因就在于,取纵坐标按横坐标排序后的最后一个元素,实际就是每个线条最右侧的纵坐标,这也是视觉上每个线条的“高度”,以此再对分组变量colour
进行排序,图例的线条顺序自然就与图中线条高低顺序一致了。
同样地,fct_reorder()
函数也可以用于可视化。
boxplot(Sepal.Width ~ Species, data = iris)
boxplot(Sepal.Width ~ fct_reorder(Species, Sepal.Width), data = iris)
<<< 左右滑动见更多 >>>
上面两幅图的区别非常直观。第二幅图的代码根据Sepal.Width
的中位数对Species
的类别进行了排序,因此图中三个箱形图的中央横线是依次升高的。
再回过头来看开头的函数描述,fct_reorder()
函数中的因子变量Species
就是图象的横轴变量,也就是位置变量(mapped to position);而fct_reorder2()
函数中的因子变量colour
是除位置变量以外的美学特征变量(mapped to a non-position aesthetic)。
推荐阅读
ggplot2基础语法系列推文汇总
胶水函数用法的几个例子
空间计量经济模型的简单形式在R语言中的实现
使用R语言的常用工具包绘制双变量填充地图
R语言基础绘图系统的拼图功能