今天的內(nèi)容主要是學習R包慎宾,包括包的安裝赦抖、加載等压鉴;并且以dplyr包進行了舉例惧所,此包中主要包含了可對數(shù)據(jù)框進行操作的相關函數(shù)骤坐。
包的概念
包(package)是一系列R函數(shù)和數(shù)據(jù)集的集合;庫(library)是電腦上的文件夾纯路,包就存儲于文件夾內(nèi)的文件中或油。在我們按照標準的步驟下載安裝了R之后,我們便已經(jīng)默認安裝了一些基礎的包驰唬。
去哪兒找包
除了R語言的核心團隊外顶岸,其他人也可以開發(fā)自己的包用于R語言功能的探索腔彰。大部分的包儲存在名為CRAN(Comprehensive R Archive Network)的在線資源庫中。我們可以應用setRepositories()
命令查看究竟有哪些資源庫或者更改默認訪問的資源庫辖佣。
> setRepositories()
--- 請選用一個貯藏處 ---
1: + CRAN
2: BioC software
3: BioC annotation
4: BioC experiment
5: CRAN (extras)
6: Omegahat
7: R-Forge
8: rforge.net
Enter one or more numbers separated by spaces and then ENTER, or 0 to cancel
Bioconductor當中包含了很多分子生物學霹抛、基因組學等相關的包,與生物信息關系比較密切卷谈。我們可以用available.packages()
函數(shù)查看某庫當中包的信息杯拐。
除此之外,我們還可以在網(wǎng)上其他的存儲庫當中找到R的文件世蔗,如大名鼎鼎的Github以及bitbucket端逼、Google Code等。
鏡像設置
正如上面所說的那樣污淋,包被存儲在在線的存儲庫里顶滩,如果我們想要使用的話,首先就要把它下載到我們自己的電腦上寸爆。但是我們用的是國內(nèi)的網(wǎng)礁鲁,儲存庫用的是國外的網(wǎng),網(wǎng)絡不好的時候下載就會出現(xiàn)問題或者耗時很長赁豆。我們可以利用鏡像網(wǎng)站巧妙地解決這個問題仅醇,感謝生信星球將這個問題講述的十分詳細,下面是我自己實操的過程:
- 方法1:在R studio的Tools→Global Options→Packages當中魔种,在Primary CRAN repository中選擇國內(nèi)的鏡像網(wǎng)站析二。但是應用起來很不穩(wěn)定:
-
方法2:利用options命令手動進行設置,代碼如下务嫡。之后我們可以用
options()$repos
和options()$BioC_mirror
命令進行檢查甲抖,發(fā)現(xiàn)確實更改成功了:
> options("repos" = c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/")) #對應清華源
> options(BioC_mirror="https://mirrors.ustc.edu.cn/bioc/") #對應中科大源
> options()$repos
CRAN
"https://mirrors.tuna.tsinghua.edu.cn/CRAN/"
> options()$BioC_mirror
[1] "https://mirrors.ustc.edu.cn/bioc/"
?它的缺點也是并不穩(wěn)定漆改,當我退出了R studio后再打開時心铃,又變回了國外的官方鏡像:
> options()$repos
CRAN
"https://cran.rstudio.com/"
attr(,"RStudio")
[1] TRUE
> options()$BioC_mirror
NULL
-
方法3:利用R的配置文件,我們首先設置
file.edit('~/.Rprofile')
挫剑,并在當中添加上面用到的兩個option()
代碼:
?保存后去扣,當我們再度打開R studio時,發(fā)現(xiàn)鏡像依然是國內(nèi)網(wǎng)站樊破。這是因為配置的原因愉棱,在打開R studio的時候,它已經(jīng)首先運行了我們制定的option()
命令:
> options()$repos
CRAN
"https://mirrors.tuna.tsinghua.edu.cn/CRAN/"
> options()$BioC_mirror
[1] "https://mirrors.ustc.edu.cn/bioc/"
R studio中有兩個最重要的配置文件,在剛開始運行Rstudio的時候哲戚,程序會查看許多配置內(nèi)容:
① .Renviron:設置R的環(huán)境變量奔滑;
② .Rprofile:一個代碼文件,如果啟動時找到這個文件顺少,那么就替我們先運行一遍
包的安裝
- 方法1:在Rstudio的Tools選項中點擊Install Package
-
方法2:根據(jù)包的來源不同我們可以通過
install.packages(“包”)
命令或者
BiocManager::install(“包”)
命令進行包的安裝朋其。事實上王浴,在想要安裝一個包時,首先在網(wǎng)絡上搜索一下它的名字梅猿,便會查找到許多相關的幫助氓辣。
install.packages常用的參數(shù):
pkg:要安裝的包的名字,如果是連接網(wǎng)絡下載可直接寫出報名袱蚓,利用參數(shù)c(“包1”,"包2“)可以一次下載多個包钞啸。如果安裝已經(jīng)下載的包(tar.gz/tgz/zip文件),可以直接寫上這些本地包的路徑喇潘,并添加repo=NULL參數(shù)体斩;
repos=:庫的基礎URL,如:CRAN 鏡像的URL颖低;如為NULL硕勿,表示包已經(jīng)被下載;
lib=:儲存到哪個庫中枫甲;如果缺少源武,默認為. libpaths()的第一個元素;
type=:包的類型,除了windows和一些Mac OS系統(tǒng)外想幻,為“source”粱栖,其余的類型包括二進制類型等
- 方法3:從Github上安裝包,具體方法如下:
install.packages("devtools") #首先安裝devtools包
library(usethis) #加載devtools之前提示我首先加載usethis包
library(devtools) #加載devtools包
install_github("包") #利用install_github包下載所需的包
包的加載
通常我們可以使用library()
來進行包的加載脏毯,包的名稱在傳遞給庫library時并不需要被引號括起來闹究。當然我們能加載出來一個包的前提是我們已經(jīng)安裝好了這個包,否則將會拋出一個錯誤食店。
另一種加載包的方式為require()
渣淤,但是它不會拋出錯誤,而是通過返回TRUE和FALSE來判斷包是否被成功加載吉嫩。
在下面的例子中价认,我們安裝了dplyr包并進行了加載:
options("repos" = c(CRAN="https://mirrors.tuna.tsinghua.edu.cn/CRAN/"))
options(BioC_mirror="https://mirrors.ustc.edu.cn/bioc/")
install.packages("dplyr")
library(dplyr)
查看已安裝的包
installed.packages()
將為我們返回已安裝包的信息,包括它的名稱自娩、版本用踩、位置、依賴的包等忙迁。為了更清晰直觀地進行查看脐彩,我們可以結合View()
命令遠離控制臺進行查看:
View(installed.packages())
此外,下面的代碼將提供給我們一些關于已安裝的包的位置的信息:
#查看R安裝時自帶的包的位置
> R.home("library")
[1] "/Library/Frameworks/R.framework/Resources/library"
> .Library
[1] "/Library/Frameworks/R.framework/Resources/library"
#查看系統(tǒng)用戶庫的位置
> path.expand("~")
[1] "/Users/maxxie"
> Sys.getenv("HOME")
[1] "/Users/maxxie"
#返回的第一個結果為包被默認安裝的位置
> .libPaths()
[1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library"
查看已加載的包
我們可以使用search()
查看已經(jīng)加載的包姊扔。其中第一位的永遠是全局環(huán)境惠奸,因而全局環(huán)境也始終在搜索列表的最前面;之后的為我們最近加載過的包恰梢;排在最末的兩個一個為特殊環(huán)境Autoloads佛南,另一個為基礎包base:
> search()
[1] ".GlobalEnv" "package:devtools" "package:usethis" "package:dplyr"
[5] "tools:rstudio" "package:stats" "package:graphics" "package:grDevices"
[9] "package:utils" "package:datasets" "package:methods" "Autoloads"
[13] "package:base"
包的維護
包括包的升級以及包的刪除证九,具體命令如下:
update.packages() #將安裝的包全部升級到最新版本
update.packages(ask = FALSE) #加上ask=FALSE參數(shù),在更新時不會進行提示
remove.packages("包") #刪除某個包
dplyr包基礎函數(shù)
以dplyr包中自帶的數(shù)據(jù)集iris進行演示共虑。該數(shù)據(jù)集向我們展示了來自三種鳶尾屬植物愧怜、共50種花的花萼長度與重量,花瓣長度與重量妈拌。我們利用[]按照數(shù)據(jù)庫索引的方式從中隨機挑選幾行賦值給新的數(shù)據(jù)框test:
test <- iris[c(1:2,51:52,101:102),] #以其中的iris數(shù)據(jù)集進行演示
下面的例子中涉及到與dplyr包中函數(shù)功能類似的base包中的函數(shù)拥坛,也選擇性地進行了探索與展示:
-
添加列:
向test數(shù)據(jù)框中添加一列new,其值為 Sepal.Length * Sepal.Width
① 我們首先可以用標準賦值符進行操作;
> test$new <- test$Sepal.Length * test$Sepal.Width
> test
Sepal.Length Sepal.Width Petal.Length Petal.Width Species new
1 5.1 3.5 1.4 0.2 setosa 17.85
2 4.9 3.0 1.4 0.2 setosa 14.70
51 7.0 3.2 4.7 1.4 versicolor 22.40
52 6.4 3.2 4.5 1.5 versicolor 20.48
101 6.3 3.3 6.0 2.5 virginica 20.79
102 5.8 2.7 5.1 1.9 virginica 15.66
?如果重復打數(shù)據(jù)框的名字太麻煩尘分,則可以使用with()
或者within()
猜惋,分別對單列或者多列進行更改。當然培愁,Day4中用過的attach()
也是有效的著摔。
?② 我們還可以使用mutate(數(shù)據(jù)框,新列名=值)
函數(shù),進行列的添加:
> mutate(test, new = Sepal.Length * Sepal.Width)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species new
1 5.1 3.5 1.4 0.2 setosa 17.85
2 4.9 3.0 1.4 0.2 setosa 14.70
3 7.0 3.2 4.7 1.4 versicolor 22.40
4 6.4 3.2 4.5 1.5 versicolor 20.48
5 6.3 3.3 6.0 2.5 virginica 20.79
6 5.8 2.7 5.1 1.9 virginica 15.66
-
列的篩選:
篩選出某些想要的列進行展示
除了利用[]進行索引外定续,還可以使用select(數(shù)據(jù)框,列名或列號)
函數(shù)進行篩選:
#按列號進行篩選
> select(test,1)
Sepal.Length
1 5.1
2 4.9
51 7.0
52 6.4
101 6.3
102 5.8
> select(test,c(1,5))
Sepal.Length Species
1 5.1 setosa
2 4.9 setosa
51 7.0 versicolor
52 6.4 versicolor
101 6.3 virginica
102 5.8 virginica
#按列名進行篩選
> select(test,Sepal.Length)
Sepal.Length
1 5.1
2 4.9
51 7.0
52 6.4
101 6.3
102 5.8
-
行的篩選:
篩選出某些想要的行進行展示
我們使用filter(數(shù)據(jù)框,邏輯式)
函數(shù)對行進行篩選谍咆,不同于select()
直接索引列名或列號,filter()
接受一個邏輯表達式并返回結果為TRUE的行:
#返回物種名為"setosa"的行
> filter(test, Species == "setosa")
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
#返回物種名為"setosa"且花萼長度大于5的行
> filter(test, Species == "setosa"&Sepal.Length > 5 )
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
#提取物種在向量c("setosa","versicolor")中的那幾行私股,即物種為"setosa"或"versicolor"的行摹察;
#A%in%B的含義為判斷A的值是否包含在B當中,返回布爾值
> filter(test, Species %in% c("setosa","versicolor"))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 7.0 3.2 4.7 1.4 versicolor
4 6.4 3.2 4.5 1.5 versicolor
-
排序
對某一列按照某種順序進行排序
①arrange(數(shù)據(jù)框,按照什么進行排序)
可僅用一行便對數(shù)據(jù)框進行排序:
arrange(test, Sepal.Length) #默認從小到大排序
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 4.9 3.0 1.4 0.2 setosa
## 2 5.1 3.5 1.4 0.2 setosa
## 3 5.8 2.7 5.1 1.9 virginica
## 4 6.3 3.3 6.0 2.5 virginica
## 5 6.4 3.2 4.5 1.5 versicolor
## 6 7.0 3.2 4.7 1.4 versicolor
arrange(test, desc(Sepal.Length)) #用desc從大到小
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 7.0 3.2 4.7 1.4 versicolor
## 2 6.4 3.2 4.5 1.5 versicolor
## 3 6.3 3.3 6.0 2.5 virginica
## 4 5.8 2.7 5.1 1.9 virginica
## 5 5.1 3.5 1.4 0.2 setosa
## 6 4.9 3.0 1.4 0.2 setosa
?②order(x)
將返回x中的數(shù)值按照由小到大排序后的排名情況倡鲸,配合索引可以在數(shù)據(jù)框中進行某種順序的排序:
> sepal.Length.order<-order(test$Sepal.Length)
> sepal.Length.order #得到的結果為test中各行的Sepal.Length由小到大的排名情況
[1] 2 1 6 5 4 3
> test[sepal.Length.order,]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
2 4.9 3.0 1.4 0.2 setosa
1 5.1 3.5 1.4 0.2 setosa
102 5.8 2.7 5.1 1.9 virginica
101 6.3 3.3 6.0 2.5 virginica
52 6.4 3.2 4.5 1.5 versicolor
51 7.0 3.2 4.7 1.4 versicolor
?③sort()
函數(shù)可以按照一定順序對數(shù)值或者字符進行排序供嚎,但是數(shù)據(jù)框無法直接應用
x<-c(2,32,4,16,8)
sort(x)
sort(x,decreasing = TRUE)
sort(c("I","A","B","E","R"))
?④rank()
函數(shù)也可以像sort()
一樣給出排名,但是在有排名相同的情況時峭状,根據(jù)參數(shù)的不同會給出不一樣的處理方式:
> (x<-sample(3,7,replace = TRUE))
[1] 1 2 2 3 3 3 2
> rank(x)
[1] 1 3 3 6 6 6 3
> rank(x,ties.method = "first")
[1] 1 2 3 5 6 7 4
-
匯總
summarize()
函數(shù)可以對常用的統(tǒng)計學指標進行匯總克滴,常見的指標如下:
常用的統(tǒng)計學指標:
- Center:
mean()
,median()
- Spread:
sd()
,IQR()
,mad()
- Range:
min()
,max()
,quantile()
- Position:
first()
,last()
,nth()
- Count:
n()
,n_distinct()
- Logical:
any()
,all()
?我們還可以結合分組函數(shù)group_by()
先分組再匯總:
#計算Sepal.Length的平均值和標準差
summarise(test, mean(Sepal.Length), sd(Sepal.Length))
## mean(Sepal.Length) sd(Sepal.Length)
## 1 5.916667 0.8084965
#先按照Species分組,計算每組Sepal.Length的平均值和標準差
group_by(test, Species)
## # A tibble: 6 x 5
## # Groups: Species [3]
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## * <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 7 3.2 4.7 1.4 versicolor
## 4 6.4 3.2 4.5 1.5 versicolor
## 5 6.3 3.3 6 2.5 virginica
## 6 5.8 2.7 5.1 1.9 virginica
#匯總分組后的結果
summarise(group_by(test, Species),mean(Sepal.Length), sd(Sepal.Length))
## # A tibble: 3 x 3
## Species `mean(Sepal.Length)` `sd(Sepal.Length)`
##
## 1 setosa 5 0.141
## 2 versicolor 6.7 0.424
## 3 virginica 6.05 0.354
-
統(tǒng)計某列的unique值
在某列中有一個數(shù)值x出現(xiàn)了n次优床,如何統(tǒng)計x出現(xiàn)了幾次
count(數(shù)據(jù)框,列名)
可以迅速實現(xiàn)這一目標劝赔,下面就對test數(shù)據(jù)集中物種每個物種出現(xiàn)了幾次進行了統(tǒng)計:
count(test,Species)
## # A tibble: 3 x 2
## Species n
##
## 1 setosa 2
## 2 versicolor 2
## 3 virginica 2
-
管道符號
就像工廠當中的流水線一樣,一個產(chǎn)品經(jīng)過了某個工人A的操作后直接傳到下一個工人B的手里羔巢,B直接拿到了A加工后的半成品望忆。
R語言當中的%>% (快捷鍵為:cmd/ctr + shift + M)則起到了管道一樣的功能罩阵,可以將前一步完成得到的那個結果直接傳給右邊/下一個函數(shù)竿秆,而不用再次將前一步驟得到的結果再次進行輸入。
運行后稿壁,結果將一氣呵成地進行展現(xiàn)幽钢,你將直接看到最終的結果:
> test %>% #將test數(shù)據(jù)框傳遞給group_by()函數(shù)
+ group_by(Species) %>% #按物種group_by()的結果傳遞給summarise()
+ summarise(mean(Sepal.Length), sd(Sepal.Length))
`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 3 x 3
Species `mean(Sepal.Length)` `sd(Sepal.Length)`
<fct> <dbl> <dbl>
1 setosa 5 0.141
2 versicolor 6.7 0.424
3 virginica 6.05 0.354
數(shù)據(jù)框的連接
數(shù)據(jù)框A和B兩者有著相同的某些行或某些列,比如一個A表中包括學生的學號傅是、姓名和數(shù)學成績匪燕,B表中包含學號蕾羊、姓名和語文成績,如何根據(jù)學號將兩表合并為學號帽驯、姓名龟再、數(shù)學成績、語文成績的綜合展現(xiàn)也是現(xiàn)實當中常常會遇到的問題:
下面的操作以兩個數(shù)據(jù)庫test1和test2進行展示尼变。兩者相同的列為x利凑,但是test1和test2里x列中的值有相同,也有不同:
> options(stringsAsFactors = F)
> test1 <- data.frame(x = c('b','e','f','x'),
+ z = c("A","B","C",'D'),
+ stringsAsFactors = F)
> test1
x z
1 b A
2 e B
3 f C
4 x D
> test2 <- data.frame(x = c('a','b','c','d','e','f'),
+ y = c(1,2,3,4,5,6), stringsAsFactors = F)
> test2
x y
1 a 1
2 b 2
3 c 3
4 d 4
5 e 5
6 f 6
-
內(nèi)連接:
取交集嫌术,函數(shù)為inner_join()
> inner_join(test1, test2, by = 'x')
x z y
1 b A 2
2 e B 5
3 f C 6
其中參數(shù)by表示按照什么進行連接:
① 如果為空哀澈,則會尋找test1和test2中所有相同的列名取交集;
② 如果輸入某一列名度气,如上面by="x"割按,則取x列中值相同的取交集;
③ 如果輸入向量磷籍,如c("x","z")适荣,則分別取test1的x和test2的x ,text1的z和test2的z的交集院领;
④ 如果輸入一個含等號的向量束凑,如c("a"="b","c"="d"),則取test1中a和test2中的b栅盲,test1中的c和test2中的d分別配對后取交集
-
左汪诉、右連接:
left_join(x,y)
會保留x中所有行,而right_join(x,y)
保留y中所有行:
#左連接谈秫,test2中相應位置沒有的值被NA替代
> left_join(test1, test2, by = 'x')
x z y
1 b A 2
2 e B 5
3 f C 6
4 x D NA
#右連接扒寄,test1中相應位置沒有的值被NA替代
> right_join(test1, test2, by = 'x')
x z y
1 b A 2
2 e B 5
3 f C 6
4 a <NA> 1
5 c <NA> 3
6 d <NA> 4
-
全連接:
full_join(test1,test2,by='列名')
可以將兩列表直接全部按照給定列名匹配后連接,相應空缺的位置被NA取代:
> full_join( test1, test2, by = 'x')
x z y
1 b A 2
2 e B 5
3 f C 6
4 x D NA
5 a <NA> 1
6 c <NA> 3
7 d <NA> 4
-
半連接:
如果我們對兩個表格進行匹配后只想保留其中一個表格的信息拟烫,可以使用半連接semi_join()
该编。例如下面的例子只展示了能與test2中x列匹配的test1的值:
> semi_join(test1,test2,by="x")
x z
1 b A
2 e B
3 f C
-
反連接:
與半連接類似,反連接anti_join
只保留不能與test2匹配的那部分test1當中的數(shù)值硕淑。將兩個例子放在一起展示更為直觀:
> semi_join(test1,test2,by="x")
x z
1 b A
2 e B
3 f C
> anti_join(x=test1,y=test2,by="x")
x z
1 x D
-
簡單連接:
在base包中有兩個連接函數(shù)rbind()
和cbind()
课竣,如果兩個數(shù)據(jù)框的大小一致,可以分別將它們“疊起來”和“左右連接拼起來”置媳。其中rbind()
會智能地對列重新排序并檢查于樟,但是cbind()
不會對列名進行重復性檢查,因此要小心使用拇囊。
在dplyr包中的bind_rows()
和bind_cols()
分別與base包中的rbind()
和cbind()
功能一致迂曲。其中,bind_rows()函數(shù)需要兩個表格列數(shù)相同寥袭,而bind_cols()函數(shù)則需要兩個數(shù)據(jù)框有相同的行數(shù):
> test1 <- data.frame(x = c(1,2,3,4), y = c(10,20,30,40))
> test1
x y
1 1 10
2 2 20
3 3 30
4 4 40
> test2 <- data.frame(x = c(5,6), y = c(50,60))
> test2
x y
1 5 50
2 6 60
> test3 <- data.frame(z = c(100,200,300,400))
> test3
z
1 100
2 200
3 300
4 400
> bind_rows(test1, test2)
x y
1 1 10
2 2 20
3 3 30
4 4 40
5 5 50
6 6 60
> bind_cols(test1, test3)
x y z
1 1 10 100
2 2 20 200
3 3 30 300
4 4 40 400
?此外路捧,如果兩個數(shù)據(jù)框具有相同的列关霸,我們還可以用merge()
函數(shù)進行連接,我們可以指定by=’x‘參數(shù)指定需要共享的那一列杰扫。如果添加all=TRUE參數(shù)队寇,則展示全部的數(shù)據(jù)框內(nèi)容,無法匹配的內(nèi)容將被用NA替代:
> test1 <- data.frame(x = c(1,2,3,4), y = c(10,20,30,40))
> test1
x y
1 1 10
2 2 20
3 3 30
4 4 40
> test2 <- data.frame(x = c(1,2,5,6), y = c(30,40,50,60))
> test2
x y
1 1 30
2 2 40
3 5 50
4 6 60
> merge(test1,test2,by='x')
x y.x y.y
1 1 10 30
2 2 20 40
> merge(test1,test2,by='x',all = TRUE)
x y.x y.y
1 1 10 30
2 2 20 40
3 3 30 NA
4 4 40 NA
5 5 NA 50
6 6 NA 60