Alluvial_0
❝小伙伴写的ggalluvial使用指南。
❞
冲击图是一种对能量分流的可视化展示图,在富集分析中可以用来展示基因在各通路中的富集流向,展示效果类比于弦图。
ggalluvial
是ggplot2
包的延伸,其设计和功能最初的灵感来自于alluvial
,对于ggalluvial
包使用方法的官方介绍参考Alluvial Plots in ggplot2 • ggalluvial (corybrunson.github.io)
「冲击图的基本结构」
- x轴是一个维度即反映了能量分流的组数,数据沿着它在固定的水平位置在垂直方向分组。上面的图中使用了三个分类轴:阶级、性别和年龄。
- 每个轴上的组绘制成不同的层次区块,称为「strata」。例如,「Class」轴包含4个层次:1、2、3和Crew。
- 水平方向的曲线被称为 「alluvia」(冲击层),示例图中冲击层对应于每个轴变量的固定值,由其在轴上的垂直位置表示,以及由其填充颜色表示的「Survived」变量的固定值。
- 在相邻轴线之间的冲击层是水流。
- 「alluvia」向右流动并与「strata」相交。图中可以获得丰富的信息,这也就意味着作图所需的数据格式至关重要。
「Alluvial数据」格式
ggalluvial
可以识别两种“冲击数据”格式,在以下各小节中有详细论述,但它们基本上对应于分类重复测量数据的“宽”和“长”格式。第三种形式是表格(或数组),用于存储具有多个分类维度的数据,如泰坦尼克号
和UCBAdmissions
的数据集为了与整洁的数据原则和ggplot2
数据格式保持一致,ggalluvial
不接受表格式输入。
宽格式数据
宽格式数据反映了冲击图的可视化排布,每一行对应一组观测,每个变量取特定值,每个变量有自己的列。另加一列,列上每行的数量,例如队列中观测单位的数量,可用于控制地层高度基本上,宽格式由每冲击层一行组成。我们用包中自带的数据进行展示。包中自带的is_alluvia_form
函数可以检查输入的数据是否符合规范。
setwd('F:/MZBJ/Alluvial') install.packages('ggalluvial') library(ggalluvial) head(as.data.frame(UCBAdmissions), n = 12) Admit Gender Dept Freq 1 Admitted Male A 512 2 Rejected Male A 313 3 Admitted Female A 89 4 Rejected Female A 19 5 Admitted Male B 353 6 Rejected Male B 207 7 Admitted Female B 17 8 Rejected Female B 8 9 Admitted Male C 120 10 Rejected Male C 205 is_alluvia_form(as.data.frame(UCBAdmissions), axes = 1:3, silent = TRUE)
这种格式继承自第一版的ggalluvial
,使用与alluvial
包相似的方法处理数据,其中stat_alluvium
和stat_stratum
以一致的方式识别和处理轴变量。
ggplot(as.data.frame(UCBAdmissions), aes(y = Freq, axis1 = Gender, axis2 = Dept)) + geom_alluvium(aes(fill = Admit),#建立冲击层 width = 1/12) + geom_stratum(width = 1/12, #建立区块 fill = "black", color = "grey") + geom_label(stat = "stratum", #添加区块标签 aes(label = after_stat(stratum))) + scale_x_discrete(limits = c("Gender", "Dept"), expand = c(.05, .05)) + scale_fill_brewer(type = "qual", palette = "Set1") + ggtitle("UC Berkeley admissions and rejections, by sex and department")
这些图的一个重要特征是垂直坐标轴的意义:区块之间没有间隔,所有图像的高度只是反映了观测值的累积量。
这种格式和功能应用前景广泛,并将在未来的版本中保留。但是仍然还涉及一些明显偏离ggplot2
规范的情况:
轴[0-9]*
位置映射是非标准的:它们不是一组显式参数,而是基于正则表达式模式的一系列参数。
Stat_alluvium
忽略组美学的任何参数;相反,StatAlluvium$compute_panel
使用group来链接对应于同一冲击层的内部转换数据集的行。
stat_stratum
产生的区块在执行统计转换之前不可用,必须使用after_stat()
恢复。
必须手动纠正水平轴(使用scale_x_discrete
或scale_x_continuous
),以反映标识轴的分类变量。
此外,对于每个冲击层来说,对于每一个冲击层fill
必须是固定的,例如,它们不能根据每个轴的值从一个轴改变到另一个轴。这意味着,尽管它们可以再现平行集的分支树结构,但这种格式和功能不能自然地产生带有配色方案的冲击图,比如这里的那些(“Controlling colors”),它们在每个轴上都被“重置”
ggplot(as.data.frame(HairEyeColor), aes(y = Freq, axis1 = Hair, axis2 = Eye, axis3 = Sex)) + geom_alluvium(aes(fill = Eye), width = 1/8, knot.pos = 0, reverse = FALSE) + scale_fill_manual(values = c(Brown = "#70493D", Hazel = "#E2AC76", Green = "#3F752B", Blue = "#81B0E4")) + guides(fill = FALSE) + geom_stratum(alpha = .25, width = 1/8, reverse = FALSE) + geom_text(stat = "stratum", aes(label = after_stat(stratum)), reverse = FALSE) + scale_x_continuous(breaks = 1:3, labels = c("Hair", "Eye", "Sex")) + coord_flip() + ggtitle("Eye colors of 592 subjects, by sex and hair color") #这一警告是由于“Hair”和“Eye”坐标轴同时具有“Brown”。
长格式数据
被ggalluvial
识别的长格式每个节点包含一行,可以理解为将dplyr格式的数据集的轴列gather
或将 excel 格式的数据集的轴列pivoting
到一个键-值对的列中,将轴编码为键,区块编码为值。这种格式需要一个额外的索引列,将对应于一个共同队列的行连接起来
UCB_lodes <- to_lodes_form(as.data.frame(UCBAdmissions), axes = 1:3, id = "Cohort") head(UCB_lodes, n = 12) Freq Cohort x stratum 1 512 1 Admit Admitted 2 313 2 Admit Rejected 3 89 3 Admit Admitted 4 19 4 Admit Rejected 5 353 5 Admit Admitted 6 207 6 Admit Rejected 7 17 7 Admit Admitted 8 8 8 Admit Rejected 9 120 9 Admit Admitted 10 205 10 Admit Rejected 11 202 11 Admit Admitted 12 391 12 Admit Rejected
在宽(「alluvia」)和长(「lodes」)格式之间转换数据的函数包括几个有助于保存辅助信息的参数。参见帮助("alluvial-data")获取示例。
相同的「stat」和「geom」可以使用不同的位置美学来接收这种格式的数据,同样也适用于碎石积层:
x
:“键”变量,表示行对应的轴,将沿水平轴排列;
stratum
,由轴变量x所表示的“值”;
alluvium
,将单个冲击层的各行连接起来的索引方案。
高度可以从轴到轴变化,允许用户生成像这里展示的凹凸图,在这些情况下,「strata」所包含的信息并不比冲击层多,而且常常没有绘制出来。为了方便起见,stat_alluvium
和stat_flow
将接受x
和「alluvium」的参数,即使对「stratum」没有给出参数例如,我们可以按地区对难民数据集中的国家进行分组,以便比较不同规模的难民数量:
install.packages('alluvial') data(Refugees, package = "alluvial") country_regions <- c( Afghanistan = "Middle East", Burundi = "Central Africa", `Congo DRC` = "Central Africa", Iraq = "Middle East", Myanmar = "Southeast Asia", Palestine = "Middle East", Somalia = "Horn of Africa", Sudan = "Central Africa", Syria = "Middle East", Vietnam = "Southeast Asia" ) Refugees$region <- country_regions[Refugees$country] ggplot(data = Refugees, aes(x = year, y = refugees, alluvium = country)) + geom_alluvium(aes(fill = country, colour = country), alpha = .75, decreasing = FALSE) + scale_x_continuous(breaks = seq(2003, 2013, 2)) + theme_bw() + theme(axis.text.x = element_text(angle = -30, hjust = 0)) + scale_fill_brewer(type = "qual", palette = "Set3") + scale_color_brewer(type = "qual", palette = "Set3") + facet_wrap(~ region, scales = "fixed") + ggtitle("refugee volume by country and region of origin")
该格式允许我们沿着同一冲击层从轴到轴的变化分配美学,这对重复测量数据集很有用。这需要为每个流生成单独的图形对象,就像在geom_flow
中实现的那样。下面的情节使用了一组(更改)学生在几个学期的课程的学术课程。由于geom_flow
默认调用stat_flow
(见下一个例子),我们用stat_alluvium
覆盖它,以便跟踪所有学期的每个学生:
data(majors) majors$curriculum <- as.factor(majors$curriculum) ggplot(majors, aes(x = semester, stratum = curriculum, alluvium = student, fill = curriculum, label = curriculum)) + scale_fill_brewer(type = "qual", palette = "Set2") + geom_flow(stat = "alluvium", lode.guidance = "frontback", color = "darkgray") + geom_stratum() + theme(legend.position = "bottom") + ggtitle("student curricula across several semesters")
区块高度y
未指定,因此每一行给定单位高度。这个例子展示了处理丢失数据的一种方法。另一种方法是设置参数na
。丢失的数据处理(具体来说,区块的顺序)也取决于区块变量是字符变量还是因子/数字变量。
最后,lode
格式为我们提供了聚合相邻轴之间的流的选项,当相邻轴之间的转换是最重要的时候,这可能是合适的。我们可以通过兰德美国生命小组(RAND American Life Panel)进行的流感疫苗接种调查数据来证明这一选择。数据,包括三个调查中每个问题的一个问题,已被汇总的回应档案:每个“主题”(映射到冲击层)实际上代表了一个队列的主题,他们以相同的方式回答所有三个问题,每个队列的大小(映射到y)被记录在“频率”。
这个图忽略了轴与轴之间的流动之间的连续性。这种“无记忆”区块产生了一个不那么混乱的中间区块,其中最多有一个流从一个轴上的每个区块 流向下一个轴上的每个区块,但代价是能够在整个地块上跟踪每个队列。