1.2 練習(xí)
(1) 運(yùn)行 ggplot(data = mpg) ,你會看到什么?
> ggplot(data = mpg)
# 空畫布
(2) 數(shù)據(jù)集 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 繪制一張散點(diǎn)圖。
ggplot(data=mpg)+geom_point(mapping = aes(x=hwy, y=cyl))
[圖片上傳失敗...(image-a89552-1585473252973)]
(5) 如果使用 class 和 drv 繪制散點(diǎn)圖,會發(fā)生什么情況?為什么這張圖沒什么用處?
ggplot(data=mpg)+geom_point(mapping = aes(x=class, y=drv))

情況:圖中的點(diǎn)沒有任何明顯趨勢。
圖沒用的原因:繪圖所選的兩個變量邏輯上一般沒有相關(guān)性,繪圖失去意義。
1.3 練習(xí)
(1) 以下這段代碼有什么錯誤?為什么點(diǎn)不是藍(lán)色的?
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy, color = "blue"))
color = "blue"應(yīng)該寫到aes()的外部、geom_point()的內(nèi)部,既:
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy), color = "blue")
當(dāng)color = "blue"寫到aes()的內(nèi)部時,會在mpg數(shù)據(jù)中搜索變量blue作為顏色映射,而mpg數(shù)據(jù)中沒有內(nèi)容為blue的變量,因此顏色默認(rèn)選擇為圖中的顏色。
(2) mpg 中的哪些變量是分類變量?哪些變量是連續(xù)變量?(提示:輸入 ?mpg 來閱讀這個數(shù)據(jù)集的文檔。)當(dāng)調(diào)用 mpg 時,如何才能看到這些信息?
- 分類變量:"manufacturer" "model" "trans" "drv" "fl" "class"
- 連續(xù)變量:"displ" "year" "cyl" "cty" "hwy"
在控制臺輸入mpg,回車,在數(shù)據(jù)每一列名的下方會有該列數(shù)據(jù)的數(shù)據(jù)類型
(3) 將一個連續(xù)變量映射為 color 、 size 和 shape 。對分類變量和連續(xù)變量來說,這些圖形屬性的表現(xiàn)有什么不同?
- 對于連續(xù)變量來說,將一個連續(xù)變量映射為 color 和 size 時,圖形和圖例也會表現(xiàn)為連續(xù),既連續(xù)的顏色或大小;但是對于連續(xù)變量來說,不能將之映射為shape,因?yàn)閟hape屬性本身是不連續(xù)的。
- 對于分類變量來說,color 、 size 和 shape三種屬性均可被之映射,每一類別對應(yīng)一種顏色、大小和形狀。
(4) 如果將同一個變量映射為多個圖形屬性,會發(fā)生什么情況?
各自顯示出其屬性。
(5) stroke 這個圖形屬性的作用是什么?它適用于哪些形狀?(提示:使用 ?geom_point 命令。)
邊框;21-24的圖形樣式,因?yàn)槠渚哂刑畛浜瓦吙?/p>
(6) 如果將圖形屬性映射為非變量名對象,比如 aes(color = displ < 5) ,會發(fā)生什么情況?
根據(jù)所映射的非變量名對象的元素個數(shù),給每個元素分配一種唯一的圖形屬性。
1.5 練習(xí)
(1) 如果使用連續(xù)變量進(jìn)行分面,會發(fā)生什么情況?
會使得每一頁的寬度或高度非常小,不便于觀看。
(2) 在使用 facet_grid(drv ~ cyl) 生成的圖中,空白單元的意義是什么?它們和以下代碼生成的圖有什么關(guān)系?
ggplot(data = mpg) + geom_point(mapping = aes(x = drv, y = cyl))
空白單元的意義是這一頁所對應(yīng)的drv和cyl值在數(shù)據(jù)中沒有對應(yīng)的組合。
上面代碼所生成的圖中沒有點(diǎn)的地方表示沒有該組合,對應(yīng)到分頁的代碼所生成的圖中即為該分頁為空白單元。
(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) 查看本節(jié)的第一個分面圖:ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy)) + facet_wrap(~ class, nrow = 2)與使用圖形屬性相比,使用分面的優(yōu)勢和劣勢分別是什么?如果有一個更大的數(shù)據(jù)集,你將如何權(quán)衡這兩種方法的優(yōu)劣?
- 優(yōu)勢:根據(jù)想要觀測的變量將數(shù)據(jù)分為每一分頁,顯示出了每一分頁中的趨勢及不同分頁之間的差別
- 劣勢:由于數(shù)據(jù)被分割為一個個的分頁,數(shù)據(jù)整體的趨勢就不能看出來了。
對于一個更大的數(shù)據(jù)來說,分頁不分頁應(yīng)該取決于你的目的。如果想看某一變量中每個元素的變化趨勢或者對不同的變化趨勢進(jìn)行比較,則選擇分頁;如果想看數(shù)據(jù)的整體趨勢,則不使用分頁。
(5) 閱讀 ?facet_wrap 的幫助頁面。 nrow 和 ncol 的功能分別是什么?還有哪些選項(xiàng)可以控制分面的布局?為什么函數(shù) facet_grid() 沒有變量 nrow 和 ncol ?
nrow:分頁的行數(shù)
ncol:分頁的列數(shù)
as.table = FALSE、dir = "v"、strip.position = "bottom"
由于facet_wrap是對單個變量進(jìn)行分頁,所以可以設(shè)置分頁的行數(shù)和列數(shù);而函數(shù)facet_grid是對兩個變量進(jìn)行分頁,無須手動設(shè)置行數(shù)和列數(shù)。
(6) 在使用函數(shù) facet_grid() 時,一般應(yīng)該將具有更多唯一值的變量放在列上。為什么這么做呢?
便于論文排版?這題不知道~~
1.6 練習(xí)
(1) 在繪制折線圖、箱線圖、直方圖和分區(qū)圖時,應(yīng)該分別使用哪種幾何對象?
- geom_line
- geom_boxplot
- geom_histogram
- facet_grid
(2) 在腦海中運(yùn)行以下代碼,并預(yù)測會有何種輸出。接著在 R 中運(yùn)行代碼,并檢查你的預(yù)測是否正確。
ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv)) +
geom_point() + geom_smooth(se = FALSE)

(3) show.legend = FALSE 的作用是什么?刪除它會發(fā)生什么情況?你覺得我為什么要在本章前面的示例中使用這句代碼?
- 隱藏圖例
- 圖例顯示
- 不知道
(4) geom_smooth() 函數(shù)中的 se 參數(shù)的作用是什么?
顯示繪制平滑線的誤差
(5) 以下代碼生成的兩張圖有什么區(qū)別嗎?為什么?
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))
沒區(qū)別。將一組映射傳遞給 ggplot() 函數(shù),ggplot2 會將這些映射作為全局映射應(yīng)用到圖中的每個幾何對象中。所以兩個代碼生成的圖相同。
(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 練習(xí)
(1) stat_summary() 函數(shù)的默認(rèn)幾何對象是什么?不使用統(tǒng)計(jì)變換函數(shù)的話,如何使用幾何對象函數(shù)重新生成以上的圖?
pointrange
ggplot(diamonds) +
geom_pointrange(
aes(cut, depth),
stat = "summary",
fun.ymin = min,
fun.ymax = max,
fun.y = median)
(2) geom_col() 函數(shù)的功能是什么?它和 geom_bar() 函數(shù)有何不同?
繪制條形圖,geom_bar自帶默認(rèn)統(tǒng)計(jì)變換屬性stat_count;而geom_col不進(jìn)行統(tǒng)計(jì)變換,默認(rèn)使用stat_identity屬性。
(3) 多數(shù)幾何對象和統(tǒng)計(jì)變換都是成對出現(xiàn)的,總是配合使用。仔細(xì)閱讀文檔,列出所有成對的幾何對象和統(tǒng)計(jì)變換。它們有什么共同之處?
參考:https://ggplot2.tidyverse.org/reference/
(4) stat_smooth() 函數(shù)會計(jì)算出什么變量?哪些參數(shù)可以控制它的行為?
- 預(yù)測值
- 均值以下的置信區(qū)間
- 均值以下的置信區(qū)間
- 標(biāo)準(zhǔn)誤差
控制行為:
- method
- formular
(5) 在比例條形圖中,我們需要設(shè)定 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..))
因?yàn)榭v軸是..prop..,即分類變量中每個類別占總量的比,group=1就是將這些類別當(dāng)作一組的這樣一個整體去分別計(jì)算各個類別的占比,所以須有g(shù)roup=1。
否則,默認(rèn)的就是各個類別各自一個“組”,在計(jì)數(shù)時就是普通的條形圖,而在計(jì)算占比時每個類別都是百分百占比,所以每個條形圖都是頂頭的一樣高。既第一條代碼所畫的圖片。
若是還有填充的映射,如fill=color,則每種顏色代表的color的一個分類在每個條形圖中都是高度為1,7種顏色堆疊在一起,縱坐標(biāo)的頂頭都是7。既第二條代碼所畫的圖片。
1.8 練習(xí)
(1) 以下圖形有什么問題?應(yīng)該如何改善?
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_point()

由于函數(shù)對統(tǒng)計(jì)值進(jìn)行了舍入取整,所以這些點(diǎn)顯示在一個網(wǎng)格上時,很多點(diǎn)彼此重疊而顯示不出來。使用geom_jitter可解決這個問題。
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_jitter()

(2) geom_jitter() 使用哪些參數(shù)來控制抖動的程度?
- width:水平方向抖動范圍
- height:垂直方向抖動范圍
(3) 對比 geom_jitter() 與 geom_count() 。
geom_jitter和geom_counter都解決了geom_point函數(shù)產(chǎn)生的過繪制問題,但又各有特點(diǎn)。
- geom_jitter可以直觀地在主圖上看到對應(yīng)位置附近的數(shù)據(jù)點(diǎn)的個數(shù)。
- geom_counter使用一個實(shí)心的黑色圓的大小來顯示改點(diǎn)附近數(shù)據(jù)點(diǎn)的個數(shù),并且用圖例顯示不同大小的圓所對應(yīng)的點(diǎn)的個數(shù)。
(4) geom_boxplot() 函數(shù)的默認(rèn)位置調(diào)整方式是什么?創(chuàng)建 mpg 數(shù)據(jù)集的可視化表示來演示一下。
position = "dodge2"
ggplot(mpg) + geom_boxplot(aes(drv, displ))

1.9 練習(xí)
(1) 使用 coord_polar() 函數(shù)將堆疊式條形圖轉(zhuǎn)換為餅圖。
ggplot(
data = diamonds,
mapping = aes(x = cut, color = clarity)) +
geom_bar(
aes(fill = clarity),
position = "identity") +
coord_polar()

(2) labs() 函數(shù)的功能是什么?閱讀一下文檔。
?labs
用于修飾所繪圖的標(biāo)題,標(biāo)簽,圖例等
(3) coord_quickmap() 函數(shù)和 coord_map() 函數(shù)的區(qū)別是什么?
coord_map() 將3D地圖垂直投影到2D平面上。它使用的是墨卡托投影,是正軸[等角圓柱投影]由荷蘭地圖學(xué)家墨卡托(G.Mercator)于1569年創(chuàng)立。假想一個與地軸方向一致的圓柱切或割于地球,按[等角條件],將經(jīng)緯網(wǎng)投影到圓柱面上,將圓柱面展為平面后,即得本投影。墨卡托投影在切[圓柱投影]與割圓柱投影中,最早也是最常用的是切圓柱投影。這種投影應(yīng)用到圖形中的每個集合對象里。 coord_quickmap() 使用一種更快的近似地圖投影。這種近似忽略掉地球的彎曲度并調(diào)整經(jīng)緯度的比例。這種轉(zhuǎn)變比coord_map() 更快。因?yàn)槊總€單獨(dú)的集合對象不需要轉(zhuǎn)變。
(4) 下圖表明城市和公路燃油效率之間有什么關(guān)系?為什么 coord_fixed() 函數(shù)很重要?geom_abline() 函數(shù)的作用是什么?
ggplot(data = mpg, mapping = aes(x = cty, y = hwy)) +
geom_point() +
geom_abline() +
coord_fixed()
- 相等
- x軸和y軸映射的變量的單位相同,要想直觀地看出兩者的關(guān)系,應(yīng)該使xy坐標(biāo)軸的一個單位具有相等的長度。因此要使用函數(shù)coord_fixed
- 添加擬合直線
補(bǔ)充作業(yè)
作業(yè)鏈接:https://www.yuque.com/docs/share/aada5877-165b-4cb8-ab96-a5260079cfbb?#
1、為什么去掉 shape = 21, 顏色 fill 不起作用?
因?yàn)橹挥?1-24號shape是填充形狀,可以設(shè)置fill屬性
2、此圖只考慮了 qvalue 是否小于 0.05,如果我們要加閾值 |log2FC >= 1| & q_value < 0.05 來將基因分為三類:上調(diào)、下調(diào)、其它;然后在此圖基礎(chǔ)上可視化。 提示:用我已經(jīng)劃分好了的 Gene_type 映射顏色,后面章節(jié)我們會學(xué)到這里函數(shù)的用法, 嘗試把 alpha、size 等參數(shù)映射進(jìn)來。
# exp <- readr::read_delim("gene_exp.diff", delim = "\t") # 注意導(dǎo)入數(shù)據(jù)時候,請導(dǎo)入我清洗后的 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") # 導(dǎo)出數(shù)據(jù)
# 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 文件復(fù)制到當(dāng)前文件夾路徑下
# 使用 getwd() 查看當(dāng)前工作目錄是在哪個地方
rm(list=ls())
library(ggplot2)
library(dplyr)
data <- readr::read_delim("test_data.txt", delim = "\t")
# 去除缺失值和無窮值,標(biāo)記數(shù)據(jù)類型
# 我自己分開的步驟
# 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")
)
# 統(tǒng)計(jì)差異基因數(shù)目(一下子沒想起來一個函數(shù),就用這個了), 下面標(biāo)記在圖中用
# 我自己的步驟
# 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
# 繪圖, 請一步一步運(yùn)行出圖,即一個加號一個加號運(yùn)行。
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) 使坐標(biāo)軸不漏縫隙,limits 指定坐標(biāo)范圍
xlab(expression(log[2]("treat" / "ctrl"))) + # Change X-Axis label
ylab(expression(-log[10]("q_value"))) + # Change Y-Axis label
theme_bw() + # 主題設(shè)置,其他主題見 ?theme_bw(),或者百度
theme(legend.position = c(0.1, 0.8), # 設(shè)置 legend 位置
legend.background = element_blank(), # 去除 legend 圖例背景
legend.key = element_rect(fill = "NA")) + # 去除 legend 圖例圈圈背景
guides(fill = guide_legend(override.aes = list(size = 5))) # 修改 legend 圖例圈圈大小
# 設(shè)置字體
# 第一次會比較久
# install.packages("extrafont")
library(extrafont)
# font_import() # 導(dǎo)入本地字體
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 的表達(dá)量之間的散點(diǎn)圖(必須繪制哈),操作也可以升華將差異基因用顏色標(biāo)記出來(此項(xiàng)不會沒關(guān)系)
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"))
