《R Data Science》读书笔记 -- Charpter 1 使用ggplot2进行数据可视化

1.2 练习

(1) 运行 ggplot(data = mpg) ,你会看到什么?
> ggplot(data = mpg)
# 空画布
(2) 数据集 mpg 中有多少行?多少列?
> dim(mpg)
[1] 234  11
# 234行,11列
(3) 变量 drv 的意义是什么?使用 ?mpg 命令阅读帮助文件以找出答案。
> ?mpg
# drv
# f = front-wheel drive, r = rear wheel drive, 4 = 4wd
(4) 使用 hwy 和 cyl 绘制一张散点图。
ggplot(data=mpg)+geom_point(mapping = aes(x=hwy, y=cyl))

[图片上传失败...(image-a89552-1585473252973)]

(5) 如果使用 class 和 drv 绘制散点图,会发生什么情况?为什么这张图没什么用处?
ggplot(data=mpg)+geom_point(mapping = aes(x=class, y=drv))

情况:图中的点没有任何明显趋势。

图没用的原因:绘图所选的两个变量逻辑上一般没有相关性,绘图失去意义。


1.3 练习

(1) 以下这段代码有什么错误?为什么点不是蓝色的?
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = "blue"))

color = "blue"应该写到aes()的外部、geom_point()的内部,既:

ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy), color = "blue")

当color = "blue"写到aes()的内部时,会在mpg数据中搜索变量blue作为颜色映射,而mpg数据中没有内容为blue的变量,因此颜色默认选择为图中的颜色。

(2) mpg 中的哪些变量是分类变量?哪些变量是连续变量?(提示:输入 ?mpg 来阅读这个数据集的文档。)当调用 mpg 时,如何才能看到这些信息?
  • 分类变量:"manufacturer" "model" "trans" "drv" "fl" "class"
  • 连续变量:"displ" "year" "cyl" "cty" "hwy"

在控制台输入mpg,回车,在数据每一列名的下方会有该列数据的数据类型

(3) 将一个连续变量映射为 color 、 size 和 shape 。对分类变量和连续变量来说,这些图形属性的表现有什么不同?
  • 对于连续变量来说,将一个连续变量映射为 color 和 size 时,图形和图例也会表现为连续,既连续的颜色或大小;但是对于连续变量来说,不能将之映射为shape,因为shape属性本身是不连续的。
  • 对于分类变量来说,color 、 size 和 shape三种属性均可被之映射,每一类别对应一种颜色、大小和形状。
(4) 如果将同一个变量映射为多个图形属性,会发生什么情况?

各自显示出其属性。

(5) stroke 这个图形属性的作用是什么?它适用于哪些形状?(提示:使用 ?geom_point 命令。)

边框;21-24的图形样式,因为其具有填充和边框

(6) 如果将图形属性映射为非变量名对象,比如 aes(color = displ < 5) ,会发生什么情况?

根据所映射的非变量名对象的元素个数,给每个元素分配一种唯一的图形属性。


1.5 练习

(1) 如果使用连续变量进行分面,会发生什么情况?

会使得每一页的宽度或高度非常小,不便于观看。

(2) 在使用 facet_grid(drv ~ cyl) 生成的图中,空白单元的意义是什么?它们和以下代码生成的图有什么关系?
ggplot(data = mpg) + geom_point(mapping = aes(x = drv, y = cyl))

空白单元的意义是这一页所对应的drv和cyl值在数据中没有对应的组合。

上面代码所生成的图中没有点的地方表示没有该组合,对应到分页的代码所生成的图中即为该分页为空白单元。

(3) 以下代码会绘制出什么图? . 的作用是什么?
ggplot(data = mpg) +geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(drv ~ .)
ggplot(data = mpg) +geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(. ~ cyl)

.的意思是在该维度不做分页。

(4) 查看本节的第一个分面图:ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy)) + facet_wrap(~ class, nrow = 2)与使用图形属性相比,使用分面的优势和劣势分别是什么?如果有一个更大的数据集,你将如何权衡这两种方法的优劣?
  • 优势:根据想要观测的变量将数据分为每一分页,显示出了每一分页中的趋势及不同分页之间的差别
  • 劣势:由于数据被分割为一个个的分页,数据整体的趋势就不能看出来了。

对于一个更大的数据来说,分页不分页应该取决于你的目的。如果想看某一变量中每个元素的变化趋势或者对不同的变化趋势进行比较,则选择分页;如果想看数据的整体趋势,则不使用分页。

(5) 阅读 ?facet_wrap 的帮助页面。 nrow 和 ncol 的功能分别是什么?还有哪些选项可以控制分面的布局?为什么函数 facet_grid() 没有变量 nrow 和 ncol ?
  • nrow:分页的行数

  • ncol:分页的列数

  • as.table = FALSE、dir = "v"、strip.position = "bottom"

由于facet_wrap是对单个变量进行分页,所以可以设置分页的行数和列数;而函数facet_grid是对两个变量进行分页,无须手动设置行数和列数。

(6) 在使用函数 facet_grid() 时,一般应该将具有更多唯一值的变量放在列上。为什么这么做呢?

便于论文排版?这题不知道~~

1.6 练习

(1) 在绘制折线图、箱线图、直方图和分区图时,应该分别使用哪种几何对象?
  • geom_line
  • geom_boxplot
  • geom_histogram
  • facet_grid
(2) 在脑海中运行以下代码,并预测会有何种输出。接着在 R 中运行代码,并检查你的预测是否正确。
ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv)) +
geom_point() + geom_smooth(se = FALSE)
(3) show.legend = FALSE 的作用是什么?删除它会发生什么情况?你觉得我为什么要在本章前面的示例中使用这句代码?
  • 隐藏图例
  • 图例显示
  • 不知道
(4) geom_smooth() 函数中的 se 参数的作用是什么?

显示绘制平滑线的误差

(5) 以下代码生成的两张图有什么区别吗?为什么?
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point() + geom_smooth()
ggplot() + geom_point(data = mpg,mapping = aes(x = displ, y = hwy)) +
geom_smooth(data = mpg,mapping = aes(x = displ, y = hwy))

没区别。将一组映射传递给 ggplot() 函数,ggplot2 会将这些映射作为全局映射应用到图中的每个几何对象中。所以两个代码生成的图相同。

(6) 自己编写 R 代码来生成以下各图。
p1 <- ggplot(data = mpg, mapping = aes(displ, hwy)) +
      geom_point(size = 2.5) +
      geom_smooth(se = F, size = 1.5)

p2 <- ggplot(data = mpg, mapping = aes(displ, hwy)) +
      geom_point(size = 2.5) +
      geom_smooth(se = F, size = 1.5, mapping = aes(group = drv))

p3 <- ggplot(data = mpg, mapping = aes(displ, hwy, color = drv)) +
      geom_point(size = 2.5) +
      geom_smooth(se = F, size = 1.5, mapping = aes(group = drv, color = drv))

p4 <- ggplot(data = mpg, mapping = aes(displ, hwy)) +
      geom_point(size = 2.5, mapping = aes(color = drv)) +
      geom_smooth(se = F, size = 1.5)

p5 <- ggplot(data = mpg, mapping = aes(displ, hwy)) +
      geom_point(size = 2.5, mapping = aes(color = drv)) +
      geom_smooth(se = F, size = 1.5, mapping = aes(group = drv, linetype = drv))

p6 <- ggplot(data = mpg, mapping = aes(displ, hwy)) +
      geom_point(size = 2.5, mapping = aes(color = drv))

library(gridExtra)
grid.arrange(p1, p2, p3, p4, p5, p6, ncol= 2, nrow = 3)

1.7 练习

(1) stat_summary() 函数的默认几何对象是什么?不使用统计变换函数的话,如何使用几何对象函数重新生成以上的图?
  • pointrange

ggplot(diamonds) +
geom_pointrange(
   aes(cut, depth), 
   stat = "summary",
   fun.ymin = min,
   fun.ymax = max,
   fun.y = median)
(2) geom_col() 函数的功能是什么?它和 geom_bar() 函数有何不同?

绘制条形图,geom_bar自带默认统计变换属性stat_count;而geom_col不进行统计变换,默认使用stat_identity属性。

(3) 多数几何对象和统计变换都是成对出现的,总是配合使用。仔细阅读文档,列出所有成对的几何对象和统计变换。它们有什么共同之处?

参考:https://ggplot2.tidyverse.org/reference/

(4) stat_smooth() 函数会计算出什么变量?哪些参数可以控制它的行为?
  • 预测值
  • 均值以下的置信区间
  • 均值以下的置信区间
  • 标准误差

控制行为:

  • method
  • formular
(5) 在比例条形图中,我们需要设定 group = 1 ,这是为什么呢?换句话说,以下两张图会有什么问题?
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, y = ..prop..))
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = color, y = ..prop..))

因为纵轴是..prop..,即分类变量中每个类别占总量的比,group=1就是将这些类别当作一组的这样一个整体去分别计算各个类别的占比,所以须有group=1。
否则,默认的就是各个类别各自一个“组”,在计数时就是普通的条形图,而在计算占比时每个类别都是百分百占比,所以每个条形图都是顶头的一样高。既第一条代码所画的图片。
若是还有填充的映射,如fill=color,则每种颜色代表的color的一个分类在每个条形图中都是高度为1,7种颜色堆叠在一起,纵坐标的顶头都是7。既第二条代码所画的图片。

1.8 练习

(1) 以下图形有什么问题?应该如何改善?
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_point()

由于函数对统计值进行了舍入取整,所以这些点显示在一个网格上时,很多点彼此重叠而显示不出来。使用geom_jitter可解决这个问题。

ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
   geom_jitter()
(2) geom_jitter() 使用哪些参数来控制抖动的程度?
  • width:水平方向抖动范围
  • height:垂直方向抖动范围
(3) 对比 geom_jitter() 与 geom_count() 。

geom_jitter和geom_counter都解决了geom_point函数产生的过绘制问题,但又各有特点。

  • geom_jitter可以直观地在主图上看到对应位置附近的数据点的个数。
  • geom_counter使用一个实心的黑色圆的大小来显示改点附近数据点的个数,并且用图例显示不同大小的圆所对应的点的个数。
(4) geom_boxplot() 函数的默认位置调整方式是什么?创建 mpg 数据集的可视化表示来演示一下。
  • position = "dodge2"

ggplot(mpg) + geom_boxplot(aes(drv, displ))

1.9 练习

(1) 使用 coord_polar() 函数将堆叠式条形图转换为饼图。
ggplot(
   data = diamonds,
   mapping = aes(x = cut, color = clarity)) +
geom_bar(
   aes(fill = clarity),
   position = "identity") +
coord_polar()
(2) labs() 函数的功能是什么?阅读一下文档。
?labs

用于修饰所绘图的标题,标签,图例等

(3) coord_quickmap() 函数和 coord_map() 函数的区别是什么?

coord_map() 将3D地图垂直投影到2D平面上。它使用的是墨卡托投影,是正轴[等角圆柱投影]由荷兰地图学家墨卡托(G.Mercator)于1569年创立。假想一个与地轴方向一致的圆柱切或割于地球,按[等角条件],将经纬网投影到圆柱面上,将圆柱面展为平面后,即得本投影。墨卡托投影在切[圆柱投影]与割圆柱投影中,最早也是最常用的是切圆柱投影。这种投影应用到图形中的每个集合对象里。 coord_quickmap() 使用一种更快的近似地图投影。这种近似忽略掉地球的弯曲度并调整经纬度的比例。这种转变比coord_map() 更快。因为每个单独的集合对象不需要转变。

(4) 下图表明城市和公路燃油效率之间有什么关系?为什么 coord_fixed() 函数很重要?geom_abline() 函数的作用是什么?
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_point() +
geom_abline() +
coord_fixed()
  • 相等
  • x轴和y轴映射的变量的单位相同,要想直观地看出两者的关系,应该使xy坐标轴的一个单位具有相等的长度。因此要使用函数coord_fixed
  • 添加拟合直线

补充作业

作业链接:https://www.yuque.com/docs/share/aada5877-165b-4cb8-ab96-a5260079cfbb?#

1、为什么去掉 shape = 21, 颜色 fill 不起作用?

因为只有21-24号shape是填充形状,可以设置fill属性

2、此图只考虑了 qvalue 是否小于 0.05,如果我们要加阈值 |log2FC >= 1| & q_value < 0.05 来将基因分为三类:上调、下调、其它;然后在此图基础上可视化。 提示:用我已经划分好了的 Gene_type 映射颜色,后面章节我们会学到这里函数的用法, 尝试把 alpha、size 等参数映射进来。
# exp <- readr::read_delim("gene_exp.diff", delim = "\t") # 注意导入数据时候,请导入我清洗后的 test_data.txt 文件
# 
# library(tidyverse)
# data <- exp[, -c(1:7)] %>% # 去除 1-7 列
#    mutate(Gene_name = paste("Gene", 1:nrow(.), sep = "_")) %>% # 增加自定义基因名列
#    select(Gene_name, everything()) %>%  # 将 Gene_name 列放置于最前面
#    rename(Ctrl_fpkm = value_1,
#           Treat_fpkm = value_2,
#           log2FC = `log2(fold_change)`) # 重新命名列名
# 
# readr::write_delim(data, "test_data.txt", delim = "\t") # 导出数据

# remove rows with NaN and lnf 
# https://www.dummies.com/programming/r/how-to-handle-infinity-in-r/
# check is.finite(), is.infinite(), ia.nan(), is.na() function

##################################################################
# 从这里开始,上面只是记录处理前面的过程
##################################################################
# 将 test_data.txt 文件复制到当前文件夹路径下
# 使用 getwd() 查看当前工作目录是在哪个地方
rm(list=ls())
library(ggplot2)
library(dplyr)
data <- readr::read_delim("test_data.txt", delim = "\t")
# 去除缺失值和无穷值,标记数据类型

# 我自己分开的步骤
# filter_data_1 = na.omit(data)
# filter_data_2 = filter(filter_data_1, !is.infinite(log2FC))
# filter_data_mine = mutate(filter_data_2, Gene_type = case_when(
#    log2FC >= 1 & q_value < 0.05 ~ "up",
#    log2FC <= -1 & q_value < 0.05 ~ "down",
#    TRUE ~ "None")
# )

filter_data <- data %>%
   na.omit() %>%
   filter(!is.infinite(log2FC)) %>%
   mutate(Gene_type = case_when(
      log2FC >= 1 & q_value < 0.05 ~ "up",
      log2FC <= -1 & q_value < 0.05 ~ "down",
      TRUE ~ "None")
   )

# 统计差异基因数目(一下子没想起来一个函数,就用这个了), 下面标记在图中用  

# 我自己的步骤
# group = dplyr::group_by(filter_data_mine, Gene_type)
# summarise(group, n())

filter_data %>%
   dplyr::group_by(Gene_type) %>%
   summarise(n())
# A tibble: 3 x 2
# Gene_type `n()`
# <chr>     <int>
#   1 down       1666
# 2 None      19298
# 3 up         1017


# 绘图, 请一步一步运行出图,即一个加号一个加号运行。
p <- ggplot(filter_data, aes(x = log2FC, y = -log10(q_value), fill = significant)) +
   geom_point(alpha = 0.5, na.rm = T, position = "jitter", shape = 21) +
   scale_fill_manual(values = c("yes" = "blue", "no" = "grey")) +  # 自己指定颜色
   geom_hline(yintercept = -log10(0.05), colour = "black", linetype = "dashed") +  # 添加 q_value 阈值线
   geom_vline(xintercept = 1, colour = "black", linetype = "dashed", size = 1) + 
   geom_vline(xintercept = -1, colour = "black", linetype = "dashed", size = 1) +
   scale_x_continuous(expand = c(0, 0), limits = c(-15, 15)) +
   scale_y_continuous(expand = c(0, 0), limits = c(0, 4)) + # expand = c(0, 0) 使坐标轴不漏缝隙,limits 指定坐标范围
   xlab(expression(log[2]("treat" / "ctrl"))) + # Change X-Axis label
   ylab(expression(-log[10]("q_value"))) + # Change Y-Axis label
   theme_bw() +  # 主题设置,其他主题见 ?theme_bw(),或者百度
   theme(legend.position = c(0.1, 0.8), # 设置 legend 位置
         legend.background = element_blank(), # 去除 legend 图例背景
         legend.key = element_rect(fill = "NA")) + # 去除 legend 图例圈圈背景
   guides(fill = guide_legend(override.aes = list(size = 5))) # 修改 legend 图例圈圈大小


# 设置字体
# 第一次会比较久
# install.packages("extrafont")
library(extrafont)
# font_import() # 导入本地字体
loadfonts(device="win")       #Register fonts for Windows bitmap output
fonts() 

p + theme(axis.text.y   = element_text(size = 12,  colour = "black", face = "bold"),
          axis.text.x   = element_text(size = 12,  colour = "black", face = "bold"),
          axis.title.x  = element_text(size = 18, face = "bold"),
          axis.title.y  = element_text(size = 18, face = "bold"),
          legend.text = element_text(size = 12,  colour = "black"),
          legend.title = element_text(size = 12,  colour = "black", face = "bold"),
          text = element_text(family="Times New Roman"))
3、绘制 ctrl 与 treat 的表达量之间的散点图(必须绘制哈),操作也可以升华将差异基因用颜色标记出来(此项不会没关系)
ggplot(filter_data, aes(x = log2(Ctrl_fpkm + 1), y = log2(Treat_fpkm + 1), fill = Gene_type)) +
   geom_point(alpha = 0.5, na.rm = T, position = "jitter", shape = 21) +
   scale_fill_manual(values = c("down" = "blue", "None" = "grey", "up"="red")) +
   scale_x_continuous(expand = c(0, 0), limits = c(-1, 15)) +
   scale_y_continuous(expand = c(0, 0), limits = c(-1, 15)) + # expand = c(0, 0)
   xlab(expression(log[2]("Ctrl_fpkm" + 1 ))) + # Change X-Axis label
   ylab(expression(log[2]("Treat_fpkm" + 1 ))) + # Change Y-Axis label
   theme_bw() +
   guides(fill = guide_legend(override.aes = list(size = 5))) + 
   theme(legend.position = c(0.2, 0.8), 
         legend.background = element_blank(), 
         legend.key = element_rect(fill = "NA"),
         axis.text.y   = element_text(size = 12,  colour = "black", face = "bold"),
         axis.text.x   = element_text(size = 12,  colour = "black", face = "bold"),
         axis.title.x  = element_text(size = 18, face = "bold"),
         axis.title.y  = element_text(size = 18, face = "bold"),
         legend.text = element_text(size = 12,  colour = "black"),
         legend.title = element_text(size = 12,  colour = "black", face = "bold"),
         text = element_text(family="Times New Roman"))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容