R语言学习 - 热图美化 (数值标准化和调整坐标轴顺序)
生物信息学习的正确姿势
NGS系列文章包括NGS基础、在线绘图、转录组分析 (Nature重磅综述|关于RNA-seq你想知道的全在这)、ChIP-seq分析 (ChIP-seq基本分析流程)、单细胞测序分析 (重磅综述:三万字长文读懂单细胞RNA测序分析的最佳实践教程)、DNA甲基化分析、重测序分析、GEO数据挖掘(典型医学设计实验GEO数据分析 (step-by-step))、批次效应处理等内容。
温故知新
R语言 - 入门环境Rstudio
R语言 - 热图绘制 (heatmap)
R语言 - 基础概念和矩阵操作
R语言 - 热图简化
热图美化
上一期的绘图命令中,最后一行的操作抹去了之前设定的横轴标记的旋转,最后出来的图比较难看。上次我们是这么写的
p <- p + xlab("samples") + theme_bw() + theme(panel.grid.major = element_blank()) + theme(legend.key=element_blank())
为了使横轴旋转45度,需要把这句话:
theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1))
放在theme_bw()
的后面。
p <- p + theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1))
最后的图应该是下边样子的。
上图的测试数据,数值的分布比较均一,相差不是太大,但是Gene_4和Gene_5由于整体的值低于其它的基因,从颜色上看,不仔细看,看不出差别。
实际应用中,异常值的出现会毁掉一张热图,如下是一个例子。
data <- c(rnorm(5,mean=5), rnorm(5,mean=20), rnorm(5, mean=100), c(600,700,800,900,10000))
data <- matrix(data, ncol=5, byrow=T)
data <- as.data.frame(data)
rownames(data) <- letters[1:4]
colnames(data) <- paste("Grp", 1:5, sep="_")
data
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5
a 5.958073 5.843652 3.225465 4.886184 3.411362
b 19.630582 20.376791 20.744580 18.534027 20.638288
c 100.351299 99.849900 102.197343 98.583629 99.540488
d 600.000000 700.000000 800.000000 900.000000 10000.000000
data$ID <- rownames(data)
data
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5 ID
a 5.958073 5.843652 3.225465 4.886184 3.411362 a
b 19.630582 20.376791 20.744580 18.534027 20.638288 b
c 100.351299 99.849900 102.197343 98.583629 99.540488 c
d 600.000000 700.000000 800.000000 900.000000 10000.000000 d
data_m <- melt(data, id.vars=c("ID"))
head(data_m)
ID variable value
1 a Grp_1 5.958073
2 b Grp_1 19.630582
3 c Grp_1 100.351299
4 d Grp_1 600.000000
5 a Grp_2 5.843652
6 b Grp_2 20.376791
p <- ggplot(data_m, aes(x=variable,y=ID)) + xlab("samples") + theme_bw() + theme(panel.grid.major = element_blank()) + theme(legend.key=element_blank()) + theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1)) + theme(legend.position="top") + geom_tile(aes(fill=value)) + scale_fill_gradient(low = "white", high = "red")
p
dev.off()
输出的结果是这个样子的
图中只有右上角可以看到红色,其他地方就没了颜色的差异。这通常不是我们想要的。为了更好的可视化效果,需要对数据做些预处理,主要有 对数转换
,Z-score转换
,抹去异常值
,非线性颜色
等方式。
对数转换
为了方便描述,假设下面的数据是基因表达数据,4个基因 (a, b, c, d)和5个样品 (Grp_1, Grp_2, Grp_3, Grp_4),矩阵中的值代表基因表达FPKM值。
data <- c(rnorm(5,mean=5), rnorm(5,mean=20), rnorm(5, mean=100), c(600,700,800,900,10000))
data <- matrix(data, ncol=5, byrow=T)
data <- as.data.frame(data)
rownames(data) <- letters[1:4]
colnames(data) <- paste("Grp", 1:5, sep="_")
data
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5
a 6.61047 20.946720 100.133106 600.000000 5.267921
b 20.80792 99.865962 700.000000 3.737228 19.289715
c 100.06930 800.000000 6.252753 21.464081 98.607518
d 900.00000 3.362886 20.334078 101.117728 10000.000000
# 对数转换
# +1是为了防止对0取对数;是加1还是加个更小的值取决于数据的分布。
# 加的值一般认为是检测的低阈值,低于这个值的数字之间的差异可以忽略。
data_log <- log2(data+1)
data_log
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5
a 2.927986 4.455933 6.660112 9.231221 2.647987
b 4.446780 6.656296 9.453271 2.244043 4.342677
c 6.659201 9.645658 2.858529 4.489548 6.638183
d 9.815383 2.125283 4.415088 6.674090 13.287857
data_log$ID = rownames(data_log)
data_log_m = melt(data_log, id.vars=c("ID"))p <- ggplot(data_log_m, aes(x=variable,y=ID)) + xlab("samples") + ylab(NULL) + theme_bw() + theme(panel.grid.major = element_blank()) + theme(legend.key=element_blank()) + theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1)) + theme(legend.position="top") + geom_tile(aes(fill=value)) + scale_fill_gradient(low = "white", high = "red")
ggsave(p, filename="heatmap_log.pdf", width=8, height=12, units=c("cm"),colormodel="srgb")
对数转换后的数据,看起来就清晰的多了。而且对数转换后,数据还保留着之前的变化趋势,不只是基因在不同样品之间的表达可比 (同一行的不同列),不同基因在同一样品的值也可比 (同一列的不同行) (不同基因之间比较表达值存在理论上的问题,即便是按照长度标准化之后的FPKM也不代表基因之间是完全可比的)。
Z-score转换
Z-score
又称为标准分数,是一组数中的每个数减去这一组数的平均值再除以这一组数的标准差,代表的是原始分数距离原始平均值的距离,以标准差为单位。可以对不同分布的各原始分数进行比较,用来反映数据的相对变化趋势,而非绝对变化量。
data_ori <- "Grp_1;Grp_2;Grp_3;Grp_4;Grp_5
a;6.6;20.9;100.1;600.0;5.2
b;20.8;99.8;700.0;3.7;19.2
c;100.0;800.0;6.2;21.4;98.6
d;900;3.3;20.3;101.1;10000"data <- read.table(text=data_ori, header=T, row.names=1, sep=";", quote="")# 去掉方差为0的行,也就是值全都一致的行
data <- data[apply(data,1,var)!=0,]data
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5
a 6.6 20.9 100.1 600.0 5.2
b 20.8 99.8 700.0 3.7 19.2
c 100.0 800.0 6.2 21.4 98.6
d 900.0 3.3 20.3 101.1 10000.0
# 标准化数据,获得Z-score,并转换为data.frame
data_scale <- as.data.frame(t(apply(data,1,scale)))# 重命名列
colnames(data_scale) <- colnames(data)
data_scale
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5
a -0.5456953 -0.4899405 -0.1811446 1.7679341 -0.5511538
b -0.4940465 -0.2301542 1.7747592 -0.5511674 -0.4993911
c -0.3139042 1.7740182 -0.5936858 -0.5483481 -0.3180801
d -0.2983707 -0.5033986 -0.4995116 -0.4810369 1.7823177
data_scale$ID = rownames(data_scale)
data_scale_m = melt(data_scale, id.vars=c("ID"))p <- ggplot(data_scale_m, aes(x=variable,y=ID)) + xlab("samples") + ylab(NULL) + theme_bw() + theme(panel.grid.major = element_blank()) + theme(legend.key=element_blank()) + theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1)) + geom_tile(aes(fill=value)) + scale_fill_gradient(low = "white", high = "red")
ggsave(p, filename="heatmap_scale.pdf", width=8, height=12, units=c("cm"),colormodel="srgb")
Z-score
转换后,颜色分布也相对均一了,每个基因在不同样品之间的表达的高低一目了然。但是不同基因之间就完全不可比了。
抹去异常值
粗暴一点,假设检测饱和度为100,大于100的值都视为100对待。
data_ori <- "Grp_1;Grp_2;Grp_3;Grp_4;Grp_5
a;6.6;20.9;100.1;600.0;5.2
b;20.8;99.8;700.0;3.7;19.2
c;100.0;800.0;6.2;21.4;98.6
d;900;3.3;20.3;101.1;10000"data <- read.table(text=data_ori, header=T, row.names=1, sep=";", quote="")data[data>100] <- 100
data
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5
a 6.6 20.9 100.0 100.0 5.2
b 20.8 99.8 100.0 3.7 19.2
c 100.0 100.0 6.2 21.4 98.6
d 100.0 3.3 20.3 100.0 100.0
data$ID = rownames(data)
data_m = melt(data, id.vars=c("ID"))p <- ggplot(data_m, aes(x=variable,y=ID)) + xlab("samples") + ylab(NULL) + theme_bw() + theme(panel.grid.major = element_blank()) + theme(legend.key=element_blank()) + theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1)) + geom_tile(aes(fill=value)) + scale_fill_gradient(low = "white", high = "red")
ggsave(p, filename="heatmap_nooutlier.pdf", width=8, height=12, units=c("cm"),colormodel="srgb")
虽然损失了一部分信息,但整体模式还是出来了。只是在选择异常值标准时需要根据实际确认。
非线性颜色
正常来讲,颜色的赋予在最小值到最大值之间是均匀分布的。非线性颜色则是对数据比较小但密集的地方赋予更多颜色,数据大但分布散的地方赋予更少颜色,这样既能加大区分度,又最小的影响原始数值。通常可以根据数据模式,手动设置颜色区间。为了方便自动化处理,我一般选择用四分位数的方式设置颜色区间。
data_ori <- "Grp_1;Grp_2;Grp_3;Grp_4;Grp_5
a;6.6;20.9;100.1;600.0;5.2
b;20.8;99.8;700.0;3.7;19.2
c;100.0;800.0;6.2;21.4;98.6
d;900;3.3;20.3;101.1;10000"data <- read.table(text=data_ori, header=T, row.names=1, sep=";", quote="")data
Grp_1 Grp_2 Grp_3 Grp_4 Grp_5
a 6.6 20.9 100.1 600.0 5.2
b 20.8 99.8 700.0 3.7 19.2
c 100.0 800.0 6.2 21.4 98.6
d 900.0 3.3 20.3 101.1 10000.0
data$ID = rownames(data)
data_m = melt(data, id.vars=c("ID"))
# 获取数据的最大、最小、第一四分位数、中位数、第三四分位数
summary_v <- summary(data_m$value)
summary_v
Min. 1st Qu. Median Mean 3rd Qu. Max.3.30 16.05 60.00 681.40 225.80 10000.00
# 在最小值和第一四分位数之间划出6个区间,第一四分位数和中位数之间划出6个区间,中位数和第三四分位数之间划出5个区间,最后的数划出5个区间
break_v <- unique(c(seq(summary_v[1]*0.95,summary_v[2],length=6),seq(summary_v[2],summary_v[3],length=6),seq(summary_v[3],summary_v[5],length=5),seq(summary_v[5],summary_v[6]*1.05,length=5)))
break_v
[1] 3.135 5.718 8.301 10.884 13.467 16.050 24.840[8] 33.630 42.420 51.210 60.000 101.450 142.900 184.350
[15] 225.800 2794.350 5362.900 7931.450 10500.000
# 安照设定的区间分割数据
# 原始数据替换为了其所在的区间的数值
data_m$value <- cut(data_m$value, breaks=break_v,labels=break_v[2:length(break_v)])
break_v=unique(data_m$value)data_m
ID variable value
1 a Grp_1 8.301
2 b Grp_1 24.84
3 c Grp_1 101.45
4 d Grp_1 2794.35
5 a Grp_2 24.84
6 b Grp_2 101.45
7 c Grp_2 2794.35
8 d Grp_2 5.718
9 a Grp_3 101.45
10 b Grp_3 2794.35
11 c Grp_3 8.301
12 d Grp_3 24.84
13 a Grp_4 2794.35
14 b Grp_4 5.718
15 c Grp_4 24.84
16 d Grp_4 101.45
17 a Grp_5 5.718
18 b Grp_5 24.84
19 c Grp_5 101.45
20 d Grp_5 10500
# 虽然看上去还是数值,但已经不是数字类型了
# 而是不同的因子了,这样就可以对不同的因子赋予不同的颜色了
> is.numeric(data_m$value)
[1] FALSE
> is.factor(data_m$value)
[1] TRUE
break_v
#[1] 8.301 24.84 101.45 2794.35 5.718 10500
#18 Levels: 5.718 8.301 10.884 13.467 16.05 24.84 33.63 42.42 51.21 … 10500
# 产生对应数目的颜色
gradientC=c('green','yellow','red')
col <- colorRampPalette(gradientC)(length(break_v))
col
#[1] "#00FF00" "#66FF00" "#CCFF00" "#FFCB00" "#FF6500" "#FF0000"
p <- ggplot(data_m, aes(x=variable,y=ID)) + xlab("samples") + ylab(NULL) + theme_bw() + theme(panel.grid.major = element_blank()) + theme(legend.key=element_blank()) + theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1)) + geom_tile(aes(fill=value))# 与上面不同的地方,使用的是scale_fill_manual逐个赋值
p <- p + scale_fill_manual(values=col)
ggsave(p, filename="heatmap_nonlinear.pdf", width=8, height=12, units=c("cm"),colormodel="srgb")
调整行的顺序或列
如果想保持图中每一行的顺序与输入的数据框一致,需要设置因子的水平。这也是ggplot2
中调整图例或横纵轴字符顺序的常用方式。
data_rowname <- rownames(data)
data_rowname <- as.vector(rownames(data))
data_rownames <- rev(data_rowname)
data_log_m$ID <- factor(data_log_m$ID, levels=data_rownames, ordered=T)
p <- ggplot(data_log_m, aes(x=variable,y=ID)) + xlab(NULL) + ylab(NULL) + theme_bw() + theme(panel.grid.major = element_blank()) + theme(legend.key=element_blank()) + theme(axis.text.x=element_text(angle=45,hjust=1, vjust=1)) + theme(legend.position="top") + geom_tile(aes(fill=value)) + scale_fill_gradient(low = "white", high = "red")
ggsave(p, filename="heatmap_log.pdf", width=8, height=12, units=c("cm"),colormodel="srgb")
基于ggplot2的heatmap绘制到现在就差不多了,而关于数据可视化还有很多值得探索,还请留意后续分享✌
R统计和作图
Graphpad,经典绘图工具初学初探
维恩(Venn)图绘制工具大全 (在线+R包)
在R中赞扬下努力工作的你,奖励一份CheatShet
别人的电子书,你的电子书,都在bookdown
R语言 - 线图绘制
R语言 - 线图一步法
R语言 - 箱线图(小提琴图、抖动图、区域散点图)
R语言 - 箱线图一步法
R语言 - 火山图
R语言 - 富集分析泡泡图
R语言 - 散点图绘制
R语言 - 韦恩图
R语言 - 柱状图
R语言 - 图形设置中英字体
R语言 - 非参数法生存分析
R语言 - 绘制seq logo图
WGCNA分析,简单全面的最新教程
psych +igraph:共表达网络构建
一文学会网络分析——Co-occurrence网络图在R中的实现
一文看懂PCA主成分分析
富集分析DotPlot,可以服
基因共表达聚类分析和可视化
R中1010个热图绘制方法
还在用PCA降维?快学学大牛最爱的t-SNE算法吧, 附Python/R代码
一个函数抓取代谢组学权威数据库HMDB的所有表格数据
文章用图的修改和排版
network3D: 交互式桑基图
network3D 交互式网络生成
Seq logo 在线绘制工具——Weblogo
生物AI插图素材获取和拼装指导
ggplot2高效实用指南 (可视化脚本、工具、套路、配色)
图像处理R包magick学习笔记
SOM基因表达聚类分析初探
利用gganimate可视化全球范围R-Ladies(R社区性别多样性组织)发展情况
一分钟绘制磷脂双分子层:AI零基础入门和基本图形绘制
AI科研绘图(二):模式图的基本画法
你知道R中的赋值符号箭头(<-)和等号(=)的区别吗?
R语言可视化学习笔记之ggridges包
利用ComplexHeatmap绘制热图(一)
ggplot2学习笔记之图形排列
R包reshape2,轻松实现长、宽数据表格转换
用R在地图上绘制网络图的三种方法
PCA主成分分析实战和可视化 附R代码和测试数据
iTOL快速绘制颜值最高的进化树!
12个ggplot2扩展包帮你实现更强大的可视化
编程模板-R语言脚本写作:最简单的统计与绘图,包安装、命令行参数解析、文件读取、表格和矢量图输出
R语言统计入门课程推荐——生物科学中的数据分析Data Analysis for the Life Sciences
数据可视化基本套路总结
你知道R中的赋值符号箭头
<-
和等号=
的区别吗?使用dplyr进行数据操作30例
交集intersect、并集union、找不同setdiff
R包reshape2,轻松实现长、宽数据表格转换
1数据类型(向量、数组、矩阵、 列表和数据框)
2读写数据所需的主要函数、与外部环境交互
3数据筛选——提取对象的子集
4向量、矩阵的数学运算
5控制结构
6函数及作用域
7认识循环函数lapply和sapply
8分解数据框split和查看对象str
9模拟—随机数、抽样、线性模型
1初识ggplot2绘制几何对象
2图层的使用—基础、加标签、注释
3工具箱—误差线、加权数、展示数据分布
4语法基础
5通过图层构建图像
6标度、轴和图例
7定位-分面和坐标系
8主题设置、存储导出
9绘图需要的数据整理技术
创建属于自己的调色板
28个实用绘图包,总有几个适合你
热图绘制
R做线性回归
绘图相关系数矩阵corrplot
相关矩阵可视化ggcorrplot
绘制交互式图形recharts
交互式可视化CanvasXpress
聚类分析factoextra
LDA分析、作图及添加置信-ggord
解决散点图样品标签重叠ggrepel
添加P值或显著性标记ggpubr
Alpha多样性稀释曲线rarefraction curve
堆叠柱状图各成分连线画法:突出组间变化
冲击图展示组间时间序列变化ggalluvial
桑基图riverplot
微生物环境因子分析ggvegan
五彩进化树与热图更配ggtree
多元回归树分析mvpart
随机森林randomForest 分类Classification 回归Regression
加权基因共表达网络分析WGCNA
circlize包绘制circos-plot
R语言搭建炫酷的线上博客系统
28个实用绘图包,总有几个适合你
热图绘制
R做线性回归
绘图相关系数矩阵corrplot
相关矩阵可视化ggcorrplot
绘制交互式图形recharts
交互式可视化CanvasXpress
聚类分析factoextra
LDA分析、作图及添加置信-ggord
解决散点图样品标签重叠ggrepel
添加P值或显著性标记ggpubr
Alpha多样性稀释曲线rarefraction curve
堆叠柱状图各成分连线画法:突出组间变化
冲击图展示组间时间序列变化ggalluvial
桑基图riverplot
微生物环境因子分析ggvegan
五彩进化树与热图更配ggtree
多元回归树分析mvpart
随机森林randomForest 分类Classification 回归Regression
加权基因共表达网络分析WGCNA
circlize包绘制circos-plot
R语言搭建炫酷的线上博客系统
维恩(Venn)图绘制工具大全 (在线+R包)
R包circlize:柱状图用腻了?试试好看的弦状图
获取pheatmap聚类后和标准化后的结果
增强火山图,要不要试一下?
一个震撼的交互型3D可视化R包 - 可直接转ggplot2图为3D
赠你一只金色的眼 - 富集分析和表达数据可视化
是Excel的图,不!是R的图
道友,来Rstudio里面看动画了
用了这么多年的PCA可视化竟然是错的!!!
R语言可视化学习笔记之ggridges包
往期精品(点击图片直达文字对应教程)
后台回复“生信宝典福利第一波”或点击阅读原文获取教程合集
R语言学习 - 热图美化 (数值标准化和调整坐标轴顺序)相关推荐
- R语言学习 - 热图简化
前面推出过热图绘制和热图美化,现在来一个函数绘制热图的简化方式.文后更有不用写代码的在线工具可用. R语言 - 基础概念和矩阵操作 R语言 - 热图简化 R语言 - 热图绘制 (heatmap) R语 ...
- R统计绘图 - 热图美化
欢迎关注天下博客:http://blog.genesino.com/2017/06/heatmap-beautiful/ Jump to- 热图美化 对数转换 Z-score转换 抹去异常值 非线性颜 ...
- R语言绘制热图实践(一)pheatmap包
目录 前言 pheatmap包 pheatmap简介 常用参数介绍 使用 安装 绘制样本间相关系数图(简单使用) 差异表达基因热图(进阶使用) 如何查看pheatmap的聚类结果 pheatmap总结 ...
- R语言绘制热图(其实是相关系数图)实践(二)corrplot包
目录 前言 corrplot包简介 语法和常用参数介绍 函数语法 参数介绍 实践 summary 参考资料 前言 在我的上一篇的内容中(R语言绘制热图实践(一)pheatmap包 ),我以绘制相关系数 ...
- R语言绘图—热图绘制
R语言绘图-热图绘制 原创 R语言与医学生 2022-06-24 20:59 发表于广东 热图使用颜色来表示二维图中第三个变量的变化和大小.热图能清楚直观的看到数据的变化.今天就简单介绍下R语言中热 ...
- r语言热图太大卡死怎么办_R语言学习 – 热图绘制 (heatmap)
热图绘制 热图是做分析时常用的展示方式,简单.直观.清晰.可以用来显示基因在不同样品中表达的高低.表观修饰水平的高低等.任何一个数值矩阵都可以通过合适的方式用热图展示. 本篇使用R的ggplot2包实 ...
- R语言绘制热图(pheatmap包)
前言 **热图(Heatmap)**是一种使用颜色来可视化矩阵值的数据可视化工具,目前在各大领域有广泛的应用.本期介绍用R语言pheatmap包绘制热图.使用R自带的数据集mtcars,用热图可视化其 ...
- R语言绘制热图——pheatmap
(网易云课堂,腾讯课堂生物信息讲师,高级生物信息工程师) pheatmap简介: Pretty Heatmaps--Implementation of heatmaps that offers mor ...
- matlab和r语言做热图,案例演示 | R语言绘制热图代码
本文是个人笔记,请谨慎付费[星球用户可免费看]. 我们在分析了差异表达数据之后,经常要进行热图的可视化展示. 热图(Heat map)是一个以颜色变化来显示数据的矩阵.虽然"热图" ...
最新文章
- linux系统盘使用率达到100%的问题查找和解决方法
- Windows Phone 8.1 Tiles, Notifications and Action Center
- Redis进阶-Stream多播的可持久化的消息队列
- 漂亮的花样边框html代码,手把手教你制作精美边框素材HTML代码
- 吴恩达老师经验:80%的数据+20%的模型=更好的机器学习
- jmeter中变量的作用范围_Jmeter参数化方式总结
- 小米潘多拉路由器添加节点_小米mesh好用吗?AX3600AX1800 混组测试
- Python 水仙花数
- SpringBoot笔记
- 高等数学在计算机领域的应用,计算机专业高等数学应用性改革探索论文
- caffe框架deploy文件中
- 手机文件上传ftp服务器,安卓手机文件上传 ftp服务器
- 31个惊艳的数据可视化作品,感受“数据之美”!
- 【Web技术】1395- Esbuild Bundler HMR
- 基于Java的亚马逊“手机”评论爬虫的情感分类分析
- 一次性餐具 disposable dishware
- KOL新消费品牌营销知多少
- MES 系统价格多少钱?企业如何甄选MES 厂商?
- Lightroom无法在卷计算机上,lightroom无法正常启动怎么办?解决lightroom无法启动方法...
- Python爬虫实例(5)-简单的爬虫,用XML爬取卡车图片
热门文章
- 【计算机组成原理】内存
- 【软件工程】系统规划的不同方法
- 【数字逻辑设计】Logisim构建抢答环节电路
- 需求分析——识别系统需求中的三类事件
- Linux基础笔记1
- oracle查询中over(partition by ...order by ...)用法
- python数据结构之 set
- java 原子量Atomic举例(AtomicReference)
- Codeforces Round #364 (Div. 2)C. They Are Everywhere(尺取法)
- OpenWRT开发之——对C++的支持(解决库依赖问题)