For graders and Professor: this document is intended as a tutorial in Chinese on the content of Mosaic plots with R. We combined texts from three websites, wiki, Mosaic plots with ggplot2 (https://cran.r-project.org/web/packages/ggmosaic/vignettes/ggmosaic.html) and the Chart: Mosaic section on edav.info.
We hope this document can effectively jumpstart any user (with limited language background to Chinese) with sufficient skills to assess Mosaic plots with R.
马赛克图(也称马里梅科图)是一种将两个或两个以上定性变量进行可视化的统计报告图[1],它是自旋图的多维扩展,自旋图只对一个变量的信息进行展示[2]。它给出数据的整体概况,并让识别变量之间的关系更加简单。例如,当不同类别的方框都具有相同的面积时,表示变量之间是独立的[3]。Hartigan和Kleiner于1981年创建了马赛克图,Friendly于1994年对其进行了扩展[4]。由于马赛克图很像马里梅科印刷品,因此也被称为梅科图。这是非常好的进行定性变量数据可视化的方式之一。
与柱状图和自旋图一样,每个方框的面积,与该类别内的观测值数量成正比[5]。
本页是一个正在进行中的工作。我们感谢您的任何意见。如果你想帮助改善这个页面,请考虑向我们的repo贡献。
library(readr)
library(vcd)
## Warning: package 'vcd' was built under R version 3.6.2
## Loading required package: grid
df = read_csv("/Users/hanxiaozhang/Downloads/MusicIcecream.csv")
## Parsed with column specification:
## cols(
## Age = col_character(),
## Favorite = col_character(),
## Music = col_character(),
## Freq = col_double()
## )
马赛克图需要一些时间来学习如何进行正确的阅读和绘制。特别是在刚开始的时候,我们建议循序渐进的学习绘制:先从划分一个变量开始,然后每次添加一个其他的变量。完整的马赛克图会对每个变量都进行一次拆分。
需要注意:如果你的数据有一个列是频率,就像下面的例子一样,计数列必须称为Freq。(表格Tables和矩阵matrices也可以使用,更多细节请参见?vcd::structable。)
还要注意的是:所有这些图都是用vcd::mosaic()绘制的,而不是用R里的基本函数包mosaicplot()。
df
## # A tibble: 8 x 4
## Age Favorite Music Freq
## <chr> <chr> <chr> <dbl>
## 1 old bubble gum classical 1
## 2 old bubble gum rock 1
## 3 old coffee classical 3
## 4 old coffee rock 1
## 5 young bubble gum classical 2
## 6 young bubble gum rock 5
## 7 young coffee classical 1
## 8 young coffee rock 0
vcd::mosaic(~Age, df)
vcd::mosaic(Music ~ Age, df)
需要注意的是,第一组在“年轻”和 “年长”中拆分,第二组拆分则将每个年龄段的人按照“古典”和 “摇滚”进行再次划分。
vcd::mosaic(Favorite ~ Age + Music, df)
请注意,在前面的例子中,分割的方向如下。
这是默认的方向模式:交替方向从水平方向开始。因此,我们得到如下同样的图:
vcd::mosaic(Favorite ~ Age + Music,
direction = c("h", "v", "h"), df)
可以根据需要改变方向。例如,要创建一个doubledecker图,除了最后一个变量,所有的分割都是垂直的。
vcd::mosaic(Favorite ~ Age + Music,
direction = c("v", "v", "h"), df)
需要注意的是,方向向量是按照拆分的顺序(年龄、音乐、喜爱),而不是按照公式中变量出现的顺序。在公式中,最后一个要拆分的变量要在”~”前先列出来。
填充颜色的分类是根据最后划分的维度——即因变量(本例中最喜欢的冰淇淋口味)。(如果不能正常运行,请更新到vcd的最新版本。)
vcd::mosaic(Favorite ~ Age + Music,
highlighting_fill = c("grey90", "cornflowerblue"),
df)
想要看关于标签选项的官方文档,请参见Strucplot框架中关于标签的说明。
rot_labels = 向量设置了图形四边的旋转度数–而不是变量分割顺序–这个顺序是:上、右、下、左。(与典型的基本图形顺序不同!)默认是 rot_labels = c(0, 90, 0, 90)。
vcd::mosaic(Favorite ~ Age + Music,
labeling = vcd::labeling_border(rot_labels = c(45, -45, 0, 0)),
df)
标签按照分割的顺序进行缩写(写作direction=)。缩写算法在消除元音后(如果需要的话),会返回return指定的字符数。
关于更多的格式化选项,请参见>?vcd::labeling_border。
vcd::mosaic(Favorite ~ Age + Music,
labeling = vcd::labeling_border(abbreviate_labs = c(3, 1, 6)),
df)
vcd::mosaic(Favorite ~ Age + Music,
spacing = vcd::spacing_equal(sp = unit(0, "lines")),
df)
想看更多细节, 请看 >?vcd::spacings
data(Arthritis, package = "vcd")
vcd::doubledecker(Improved ~ Treatment + Sex, data=Arthritis)
vcd::doubledecker(Music ~ Favorite + Age,
xtabs(Freq ~ Age + Music + Favorite, df))
要在ggplot2框架中创建马赛克图,请使用ggmosaic包中的geom_mosaic()。
https://cran.r-project.org/web/packages/ggmosaic/vignettes/ggmosaic.html
当您想查看多个分类变量之间的关系时,请注意以下几点
在马赛克图中,当有很多维度时,标签的可读性可能会较差。这可以通过以下方法来缓解: - 缩写名称 - 旋转标签。
长度比面积更容易判断,所以尽量使用相同宽度或高度的矩形。
更高更瘦的矩形判断效果更好(因为我们更擅长区分长度而不是面积)。
然而,间隙可以帮助提高可读性,所以请尝试不同的组合。
可在划分处有间隙
可以在层次结构中改变间隙大小。
对细分小组中的比率有好处
显示残余(residual)
强调特定群体
安东尼-尤文的《用R进行图形数据分析》第七章
本文第三部分(见以下详细内容)
用于分类数据的可视化。
可以生成条形图、堆叠条形图、马赛克图和双层图。
图是分层构造的,所以变量的排序是非常重要的。
集成在ggplot2中的geom里,允许分面(facetting)和分层(layering)。
ggmosaic主要是使用ggproto和productplots包创建的。
ggproto能够让你在自己的包中扩展ggplot2。
使用了productplots包中的数据处理方法。
为了绘制geom,需要计算xmin、xmax、ymin和ymax。
ggplot2不能处理总体数量在变化的变量群。
目前的解决方案:写成x=product(x1,x2)来同时读入变量x1和x2。
product函数。
是为了wrapper list而设计的函数。
允许它通过代码检测。
这些限制也会导致标签的问题,但这些都可以手动修复。
规则如下:
weight:选择一个权重变量
x:选择要添加到公式中的变量
写为x = product(x1, x2, …)
fill : 选择一个要填充的变量
如果变量没有在x中被调用,它将被添加到公式的首位。
conds : 选择一个变量作为条件
写为conds = product(cond1, cond2, …)
然后通过productplots函数发送这些值,以创建所需分布的公式。
#公式:
weight ~ fill + x | conds
## weight ~ fill + x | conds
如何写成代码
weight=1
x = product(Y, X)
fill=W
conds = product(Z)
这些美学设置了分配的公式。
library(ggplot2)
library(ggmosaic)
##
## Attaching package: 'ggmosaic'
## The following objects are masked from 'package:vcd':
##
## mosaic, spine
library(gridExtra)
ggplot(data = fly) +
geom_mosaic(aes(x = product(RudeToRecline), fill=RudeToRecline), na.rm=TRUE) +
labs(x="Is it rude recline? ", title='f(RudeToRecline)')
ggplot(data = fly) +
geom_mosaic(aes(x = product(DoYouRecline, RudeToRecline), fill=DoYouRecline), na.rm=TRUE) +
labs(x = "Is it rude recline? ", title='f(DoYouRecline | RudeToRecline) f(RudeToRecline)')
ggplot(data = fly) +
geom_mosaic(aes(x = product(DoYouRecline, RudeToRecline), fill=DoYouRecline, conds=product(Gender)), na.rm=TRUE, divider=mosaic("v")) + labs(x = "Is it rude recline? ", title='f(DoYouRecline, RudeToRecline| Gender)')
ggplot(data = fly) +
geom_mosaic(aes(x = product(DoYouRecline, RudeToRecline), fill=DoYouRecline), na.rm=TRUE) + labs(x = "Is it rude recline? ", title='f(DoYouRecline, RudeToRecline| Gender)') + facet_grid(Gender~.)
ggplot(data = fly) +
geom_mosaic(aes(x = product(DoYouRecline, RudeToRecline), fill=DoYouRecline), na.rm=TRUE) + labs(x = "Is it rude recline? ", title='f(DoYouRecline | RudeToRecline) f(RudeToRecline)') + theme(plot.title = element_text(size = rel(1)))
ggplot(data = fly) +
geom_mosaic(aes(x = product(RudeToRecline, DoYouRecline), fill=DoYouRecline), na.rm=TRUE) + labs(x = "" , y = "Is it rude recline? ", title='f(DoYouRecline | RudeToRecline) f(RudeToRecline)') + coord_flip() + theme(plot.title = element_text(size = rel(1)))
par(mfrow=c(2,1))
geom_mosaic独有的参数。
每个部分有四个选项。
hbar <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq), fill=FlightFreq), divider="hbar", na.rm=TRUE) + labs(x=" ", title='divider = "hbar"')
hspine <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq), fill=FlightFreq), divider="hspine", na.rm=TRUE) + labs(x=" ", title='divider = "hspine"')
vbar <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq), fill=FlightFreq), divider="vbar", na.rm=TRUE) + labs(y=" ", x="", title='divider = "vbar"')
vspine <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq), fill=FlightFreq), divider="vspine", na.rm=TRUE) + labs(y=" ", x="", title='divider = "vspine"')
hbar
hspine
vbar
vspine
h_mosaic <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Gender, Region), fill=FlightFreq), na.rm=T, divider=mosaic("h")) +
theme(axis.text.x=element_blank(), legend.position="none") +
labs(x=" ", title='divider= mosaic()')
v_mosaic <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Gender, Region), fill=FlightFreq), na.rm=T, divider=mosaic("v")) +
theme(axis.text.x=element_blank()) +
labs(x=" ", title='divider= mosaic("v")')
doubledecker <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Gender, Region), fill=FlightFreq), na.rm=T, divider=ddecker()) +
theme(axis.text.x=element_blank()) +
labs(x=" ", title='divider= ddecker()')
h_mosaic
v_mosaic
doubledecker
mosaic4 <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Gender, Region), fill=FlightFreq), na.rm=T, divider=c("vspine", "vspine", "hbar")) +
theme(axis.text.x=element_blank()) +
labs(x=" ", title='divider= c("vspine", "vspine", "hbar")')
mosaic5 <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Gender, Region), fill=FlightFreq), na.rm=T, divider=c("hbar", "vspine", "hbar")) +
theme(axis.text.x=element_blank()) +
labs(x=" ", title='divider= c("hbar", "vspine", "hbar")')
mosaic6 <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Gender, Region), fill=FlightFreq), na.rm=T, divider=c("hspine", "hspine", "hspine")) +
theme(axis.text.x=element_blank()) +
labs(x=" ", title='divider= c("hspine", "hspine", "hspine")')
mosaic7 <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Gender, Region), fill=FlightFreq), na.rm=T, divider=c("vspine", "vspine", "vspine")) +
theme(axis.text.x=element_blank()) +
labs(x=" ", title='divider= c("vspine", "vspine", "vspine")')
mosaic4
mosaic5
mosaic6
mosaic7
offset。设置第一条spine之间的空间大小
offset1 <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Region), fill=FlightFreq), na.rm=TRUE) + labs(x="Region", y=" ", title=" offset = 0.01")
offset0 <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Region), fill=FlightFreq), na.rm=TRUE, offset = 0) + labs(x="Region", y=" ", title=" offset = 0")
offset2 <- ggplot(data = fly) +
geom_mosaic(aes(x = product(FlightFreq, Region), fill=FlightFreq), na.rm=TRUE, offset = 0.02) + labs(x="Region", y=" ", title=" offset = 0.02")
offset1
offset0
offset2
library(plotly)
## Warning: package 'plotly' was built under R version 3.6.2
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
gg <-ggplot(data = fly) +
geom_mosaic(aes(x = product(DoYouRecline, RudeToRecline), fill=DoYouRecline), na.rm=TRUE) + labs(x = "Is it rude recline? ", title='f(DoYouRecline | RudeToRecline) f(RudeToRecline)')
ggplotly(gg)
Sandra D. Schlotzhauer (1 April 2007). Elementary Statistics Using JMP. SAS Institute. p. 407. ISBN 978-1-59994-428-9.
New Techniques and Technologies for Statistics II: Proceedings of the Second Bonn Seminar. IOS Press. 1 January 1997. p. 254. ISBN 978-90-5199-326-4.
Michael Friendly (1 January 1991). SAS System for Statistical Graphics. SAS Institute. pp. 512–. ISBN 978-1-55544-441-9.
SAS Institute (6 September 2013). JMP 11 Basic Analysis. SAS Institute. pp. 251–. ISBN 978-1-61290-684-3.
Martin Theus; Simon Urbanek (23 March 2011). Interactive Graphics for Data Analysis: Principles and Examples. CRC Press. ISBN 978-1-4200-1106-7.
Mosaic plot. (2019, June 16). Retrieved November 04, 2020, from https://en.wikipedia.org/wiki/Mosaic_plot