问题的根源是《R for data science》第7章EDA的两个图:
其中smaller来自diamonds数据集对carat的过滤:
smaller <- diamonds %>%
filter(carat < 3)
问题的关键是按照最新的ggplot2 3.3.0版本,同样的代码画出图的有区别:
library(patchwork)
p1 <- ggplot(data = smaller, mapping = aes(x = carat, y = price)) +
geom_boxplot(mapping = aes(group = cut_width(carat, 0.1)))
p2 <- ggplot(data = smaller, mapping = aes(x = carat, y = price)) +
geom_boxplot(mapping = aes(group = cut_number(carat, 20)))
p1 + p2
观察结果:即使指定了切分x轴连续变量,画出的图还是会去切分y轴连续变量price
提出问题:是否新版本ggplot2在处理两个连续变量的箱线图时会强制切分y轴变量?
先看一眼说明文档:
Orientation
This geom treats each axis differently and, thus, can thus have two orientations. Often the orientation is easy to deduce from a combination of the given mappings and the types of positional scales in use. Thus, ggplot2 will by default try to guess which orientation the layer should have. Under rare circumstances, the orientation is ambiguous and guessing may fail. In that case the orientation can be specified directly using the orientation parameter, which can be either "x" or "y". The value gives the axis that the geom should run along, "x" being the default orientation you would expect for the geom.
感觉箱线图的文档里并没有很详细的解析这一结果的原因..
同理检查了cut_width
和cut_number
的帮助文档并没有啥关键信息..
尝试:diamonds数据集有很多其他的连续变量,两两画图并指定切分x轴变量后观察
所有的连续变量:
variance <- c('carat','depth','table','price','x','y','z')
用嵌套循环和cowplot完成两两绘图,以cut_number
为例(49张图)
library(cowplot)
gglist <- list()
for (i in seq(along=variance)){
for (j in seq(along=variance)){
gglist[[(i-1)*7 + j]] <- ggplot(smaller,
aes_string(x = variance[i],
y = variance[j])) +
geom_boxplot(aes(group = cut_number(x, 20)))
}
}
final_p <- plot_grid(plotlist=gglist, nrow=7)
结果需要剔除x,y相同的图(对角线)
字有点小,但结果很有趣。黄色方框内的六张图的y变量均为price,也就是说当y轴变量为price,x轴为其他6个连续变量之一时,即使切分x轴变量,ggplot2 3.3依然会切分y轴的price
课本中的无论是cut_width还是cut_number,y轴变量也恰好均为price,所以出现了矛盾
接下来重新回顾课本上的两个例子,这次将坐标轴翻转回来便于观察和分析:
library(patchwork)
p1 <- ggplot(data = smaller, mapping = aes(x = carat, y = price)) +
geom_boxplot(mapping = aes(group = cut_width(carat, 0.1))) +
coor_flip()
p2 <- ggplot(data = smaller, mapping = aes(x = carat, y = price)) +
geom_boxplot(mapping = aes(group = cut_number(carat, 20))) +
coor_flip()
p1 + p2
- ggplot2 3.2
- ggplot2 3.3
对比一下有了新的发现,如果切割carat,则每个箱子上下分位数差距较大,异常值均较多
猜测:或许是由于切分carat后,每个分组的price差距和异常值均较多,已经失去了观察意义,而切割price后能观察到更有意义的结果,各组异常值较小,且能观察到一定相关性
到这里通过几个观察结果,我们已经可以下初步结论:
ggplot2 3.3画箱线图出现不切分指定变量的情况,并不是由于bug,而是由于y轴变量的某种特殊性
需要解决:price究竟和其他6个连续变量有什么区别,为什么其他变量的两两切分变量交换并切分x轴变量均没有问题
先观察7个连续变量的分布:
gglist <- list()
for (i in seq(along=variance)){
gglist[[i]] <- ggplot(smaller) +
geom_histogram(aes_string(x = variance[i]),bins=50)
}
plot_grid(plotlist=gglist)
观察:price相比其他连续变量,分布过于偏态和离散
再通过两两散点图评估相关性:
可能我统计学水平还是不够,就感觉到了一些东西但是说不出,price和其他6个连续变量的区别依然需要解决,先留个坑以后再填吧 : )