forcats | fct_reorder2函数功能详解及其在可视化中的应用

引子

最近在整理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
  • 可以看出,mpg在三个组别的平均值大小与调整后的因子类别顺序是一致的。

fct_reorder2()函数

这个函数的参数从表面上看与fct_reorder()函数有两个明显的区别:

  • 多了一个.y参数;

  • .desc参数的默认值不同。

其实,还有一个差别在同名参数.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():取.y在根据.x排序后的最后一个元素;然后以这个数值作为因子类别排序的依据;

  • first2():取.y在根据.x排序后的第一个元素;同样以这个数值作为因子类别排序的依据。

## 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")

85bdd1d5cba510cdeefd4e395a294508.png

16ec79574a4e0117690a12a75bb5f223.png

<<< 左右滑动见更多 >>>

从语句上看,第二幅图代码中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)

0e5be91a7f3987b8250ac655d5dcfe5a.png

ff3ae08b5a8b94d8005d737cd6fee986.png

<<< 左右滑动见更多 >>>

上面两幅图的区别非常直观。第二幅图的代码根据Sepal.Width的中位数对Species的类别进行了排序,因此图中三个箱形图的中央横线是依次升高的。

再回过头来看开头的函数描述,fct_reorder()函数中的因子变量Species就是图象的横轴变量,也就是位置变量(mapped to position);而fct_reorder2()函数中的因子变量colour是除位置变量以外的美学特征变量(mapped to a non-position aesthetic)。

推荐阅读

1d87932c27306c1b5230469d7de96baa.png
ggplot2基础语法系列推文汇总
106dda777bd65b3a28c7fc72f7a2847c.png
胶水函数用法的几个例子
e26163f302a93809fc56a2d22fe139ae.png
空间计量经济模型的简单形式在R语言中的实现
ada9852fc23ac3084769a2f78bc44cbf.png
使用R语言的常用工具包绘制双变量填充地图
07f24814fd070172f891c6b3ec7f4040.png
R语言基础绘图系统的拼图功能

3209bc966a4160abb2a185601c05bb6e.png
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值