3.1.R Basics

  • R语言是一个为统计分析而生的语言,生物信息所需的很多统计分析用原生的R语言都可以非常方便的实现。

  • 原生的R语言是跨平台的,也就是说理想情况下同一段R代码在不同的操作系统下(linux的各种发行版,windows,Mac等)都可以运行。但是也存在某些R package只支持特定操作系统的情况。

  • R语言有良好的软件生态

    • 对于数据分析中的很多一般性的任务(统计作图和机器学习等等),都可以在CRAN找到直接可以使用的package。

    • bioconductor积累了大量针对特定生物信息学问题开发的package。

    • 熟悉一些常用的package可以让我们避免"重复造轮子",用很少的代码迅速解决一些实际的问题,对此我们会在后续章节中陆续介绍。

  • 为了在实际的生物信息数据分析中利用好这些前人实现的R package,我们首先需要熟悉R语言的语法和内置的数据结构。本章中我们将对此进行介绍。

上机任务

iris是R语言自带的一个数据集,它默认会作为一个数据框加载到R环境中,请对iris数据做如下分析:

  • iris数据集有几列?每列的数据类型是什么?

  • 按Species列将数据分成3组,分别计算Sepal.Length的均值和标准差,保存为一个csv文件,提供代码和csv文件的内容。

  • 对不同Species的Sepal.Width进行One way ANOVA分析,提供代码和输出的结果。

提交文件格式: md(推荐),word, pdf, txt。

1) Install and Use R

  • 前面已经提到,R语言是一个跨平台的编程语言,所以在windows下也可以使用。

  • 本教程中方和R语言相关的练习,大家可以在自己的机器上安装相关工具,不一定要使用docker容器(docker容器中已经装好了R环境,但无法使用rstudio这类IDE)。

1a) Install R

请参考官方文档。这里提供了在CentOS和Ubuntu两种linux发行版用相应的包管理工具安装R的例子。

  • For CentOS

yum -y install epel-release
yum -y install R
  • For Ubuntu

apt -y install r-base

1b) Install RStudio

  • 安装了R之后,我们就可以使用R语言的交互式终端,或者用R语言解释器运行R的脚本了。

  • 如果你希望有一个对用户更友好的编程环境,推荐使用RStudio

  • RStudio是目前最流行的一个R语言集成开发环境(Integrated Development Environment, IDE),它对代码高亮,变量,图片和帮助文档的展示等等都有很好的支持。

1c) Use R

  • 和bash一样,我们可以交互式的使用R,也可以把代码组织到一个脚本中

  • 在linux终端中输入R或点击windows GUI的图标即可进入交互式的R环境

  • 我们也可以把R代码写到一个脚本中,例如在文本文件hello.R中输入以下内容:

#!/usr/bin/env Rscript
print("hello R !")
  • 输入chmod u+x hello.R给文件可执行权限

  • ./hello.R运行

  • #!/usr/bin/env Rscript告诉操作系统使用Rscript作为解释器执行脚本,手动指定解释器,如用Rscript hello.R运行也是可以的

1d) Install R packages

  • 进入交互式的R环境

  • 对于CRAN收录的R package,我们可以用install.packages命令安装

> install.packages("ggplot2")
  • 对于bioconductor收录的R package,我们需要先用install.packages命令安装bioconductor的包管理工具BiocManager,再用BiocManager::install进行安装。

  • 我们提供了一个用BiocManager package安装DESeq2这个bioconductor package(DESeq2是RNA-seq counts数据差异表达分析最常用的工具之一)。

# 如果未安装BiocManager,需要首先安装
if (!require("BiocManager", quietly = TRUE))
install.packages("BiocManager")
#利用BiocManager安装bioconductor的package
BiocManager::install("DESeq2")

2) Data type

2a) Basic data types

R语言最基本的数据类型包括 numeric(数值), logical(布尔值), character(字符), factor(因子)等。在R语言中,箭头<-和等号=都可作为赋值运算符。我们可以用class函数获得一个R语言对象的数据类型。R语言提供了各种数据类型之间相互转换的函数。

  • numeric (数值变量)

> x = 10.5 # assign a decimal value to x, x <- 10.5 also work
> x
[1] 10.5
> class(x) # print the class name of x
[1] "numeric"
> is.numeric(x) # check whether x is a numeric variable
[1] TRUE
> is.integer(x)
[1] FALSE

> y = as.integer(3)
> y 
[1] 3
> class(y) # print the class name of y
[1] "integer"
> is.numeric(y) # integer is a special numeric variable
[1] TRUE

和多数编程语言不同,"."在R语言中不是一个特殊符号,可以在变量名和函数名中使用

  • logical (布尔变量)

> x = 1; y = 2 
> z = x > y # is x larger than y?
> z # print the logical value
[1] FALSE
> class(z) # print the class name of z
[1] "logical"
> as.integer(z)
[1] 0
  • character(字符变量)

> x = as.character(10.5)
> x # print the character string
[1] "10.5"
> class(x) # print the class name of x
[1] "character"
  • factor (因子)

factor是R语言中比较独特的数据类型,它是专门用来编码类别变量(categorical variable),方便类别变量的统计分析,我们之后还会专门介绍。

> x <- as.factor("a")
> x
[1] a
Levels: a

2b) Vector

  • R语言的数组用于存储一组类型相同的变量

  • R语言中数组的下标是从1开始的

> c(2, 3, 5) # c()可以理解为一个用于concatenate(连接)的函数,它可以将数值连接成一个向量
[1] 2 3 5

> n = c(2, 3, 5)
> s = c("aa", "bb", "cc", "dd", "ee")
> c(n, s) # c()既可以用来将单个的变量连接成数组,也可以用来将多个数组连成一个数组
[1] "2" "3" "5" "aa" "bb" "cc" "dd" "ee" #数组要求元素类型相同,如果需要连接的数组类型不同c()会自动进行类型转换

> s = c("aa", "bb", "cc", "dd", "ee")

# 可以用方括号[]获取数组的元素
> s[3] # the index starts from 1
[1] "cc"

#如果定义的数组中存在不同的数据类型,R语言会自动进行类型转换
> c("aa", "bb", "cc", "dd", 2)
[1] "aa" "bb" "cc" "dd" "2" 
  • 由因子组成的数组

# 因子可以理解成有次序的一组离散变量,"Levels: a b c"表明了三个因子的次序
> x <- factor(c("a","a","b","b","b","c"))
> x
[1] a a b b b c
Levels: a b c

# 因子可以被转换为对应相应次序的整数
> as.integer(x)
[1] 1 1 2 2 2 3

# 因子的次序默认按字母表确定,也可以人为指定
> x <- factor(c("a","a","b","b","b","c"),levels=c("b","c","a"))
> x
[1] a a b b b c
Levels: b c a
#获取因子的levels
> levels(x)
[1] "b" "c" "a"

2c) Matrix

  • R中的matrix即为二维的数组,它和一维数组一样,存储相同类型的变量

> B = matrix(
+ c(2, 4, 3, 1, 5, 7),
+ nrow=3,
+ ncol=2)

> B # B has 3 rows and 2 columns
     [,1] [,2]
[1,]    2    1
[2,]    4    5
[3,]    3    7

2d) List

  • R语言中的列表(list)可以用来存储一组任意类型的变量(变量类型不一定要相同)

> n = c(2, 3, 5)
> s = c("aa", "bb", "cc", "dd", "ee")
> b = c(TRUE, FALSE, TRUE, FALSE, FALSE)
> x = list(n, s, b, 3) # x contains copies of n, s, b

> x
[[1]]
[1] 2 3 5

[[2]]
[1] "aa" "bb" "cc" "dd" "ee"

[[3]]
[1]  TRUE FALSE  TRUE FALSE FALSE

[[4]]
[1] 3

# 可以用双方括号[[]]获取列的元素
> x[[1]]
[1] 2 3 5

# 可以用字符串给列表元素命名 
> names(x) <- c("A","B","C","D")

> names(x)
[1] "A" "B" "C" "D"

# 可以用以下两种方式访问有命名的列表元素
> x[["A"]]
[1] 2 3 5

> x$A
[1] 2 3 5

2e) Data frame

  • 我们在统计分析所用到的数据在很多情况下都可以整理成每行对应单个样本,每列对应各个样本特定属性的形式,这类数据常常被称为表格数据(tabular data)

  • 数据框(data frame)主要针对这类数据的存储,可以说是R语言中最常用的一种数据类型

  • 数据框可以理解成一种特殊的列表。这个列表中的元素都是一些长度相同的数组。每一个数组对应着所有样本的特定属性,数组的长度对应样本的数量

> n = c(2, 3, 5)
> s = c("aa", "bb", "cc")
> b = c(TRUE, FALSE, TRUE)
> df = data.frame(n, s, b) # df is a data frame
> df
  n  s     b
1 2 aa  TRUE
2 3 bb FALSE
3 5 cc  TRUE

# 获取列名
> colnames(df)
[1] "n" "s" "b"
# 或
> names(df)
[1] "n" "s" "b"


# 访问特定列
# 用于访问列表元素的两种方法同样适用于数据框
> df$n
[1] 2 3 5
> df[["n"]]
[1] 2 3 5

3) Examples

3a) Read and write table

  • 如前所述,原生的R语言提供了很多针对表格数据处理的函数,其中就包括表格的输入输出

  • mtcars是R语言自带的一个数据集,以数据框的形式在R环境中默认加载,我们这里用它来作为学习表格读写的例子。我们可以输入head(mtcars)查看前几行:

> head(mtcars)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
  • write.csvwrite.table可以将数据框以文件的形式写入磁盘

# write.csv输出用逗号作为分隔符的csv(Comma-Separated Values)文件
write.csv(mtcars,"mtcars.csv")
# write.csv默认会给输出的字符串加上双引号,如果不想加可以指定quote=F
write.csv(mtcars,"mtcars.csv",quote=F)
# 用write.table除了逗号还可以指定不同的分隔符(默认为制表符"\t")
write.table(mtcars,"mtcars.txt",quote=F,sep=";") # 用";"作为分隔符
  • read.csvread.table可以从磁盘中读取表格文件

my.table <- read.csv("mtcars.csv")
my.table2 <- read.table("mtcars.txt",sep=";")

R语言中read.csv和read.table通常默认会把表格中的字符串读取成factor类型,如果不希望将字符串转变为因子,需要人为指定参数stringsAsFactors=FALSE

3b) Statistic functions

  • R语言提供了大量用于统计分析的函数,可以很方便的计算各种统计量,实现各种统计检验,我们这里提供了三个简单的例子

  • 计算均值和标准差

#计算mtcars数据集"mpg"一列的均值
> mean(mtcars$mpg)
[1] 20.09062
#计算mtcars数据集"mpg"一列的标准差
> sd(mtcars$mpg)
[1] 6.026948
  • t检验:

x=c(5.6,7.9,8.9,19.5,20.5,39.5)
y=c(6.5,8.3,9.1,17.9,29.4,22.8)

# unpaired two tail t test
t.test(x,y,alternative="two.sided")

# unpaired single tail t test for alternative hypothesis mean(x) < mean(y)
t.test(x,y,alternative="less")

# paired single tail t test
t.test(x,y,altrenative="less",paired=TRUE) 
  • One way ANOVA:

# 生成示例数据集
# 从均值为1,0,-0.5,标准差均为1的3个正态分布中各生成20个样本
R <- c(rnorm(20)+1,rnorm(20),rnorm(20)-0.5)
# 用因子类型定义分组
D <- as.factor(c(rep("A",20),rep("B",20),rep("C",20)))
# 将数据放到一个数据框中
table <- data.frame(R=R,D=D)
# 用one way anova检验A,B,C三组之间是否存在差异
summary(aov(R~D,data=table))
            Df Sum Sq Mean Sq F value   Pr(>F)    
D            2  16.65   8.323   8.417 0.000627 ***
Residuals   57  56.36   0.989                     
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

我们上面用到的R ~ D在R语言中被称为公式(formula),在统计分析和作图中都有广泛的应用。R ~ D是一个最简单的公式,"~"符号左边是因变量,右边是自变量。有兴趣深入了解的同学可参考https://www.datacamp.com/tutorial/r-formula-tutorial

3c) aggregate

  • 在原生R语言中,aggregate函数可以根据数据框的特定列进行分组计算

# 在mtcars数据集中,按"vs"列分组,计算"mpg"列的均值
> aggregate(mpg ~ vs, mtcars, mean)
  vs      mpg
1  0 16.61667
2  1 24.5571

# this approach also work
> aggregate(mtcars$mpg,by=list(vs=mtcars$vs),mean)
  vs        x
1  0 16.61667
2  1 24.55714

R package dplyr基于自己定义的一套语法,提供了比较方便的操纵数据框的功能(筛选,分组计算等等),有兴趣的同学可以自行了解

3d) More R Examples

4) More Reading and Practice

4a) Basic

  • 《Bioinformatics Data Skills》

    • A Rapid Introduction to the R Language

  • Quick R 可以从如下章节开始 :

    • Learning R

    • R Interface

    • Data Input

    • Statistics

4b) Advanced

5) References

Take a break

R,Robert, 23andMe

R语言是从S统计绘图语言演变而来。S语言上世纪70年代诞生于AT&T贝尔实验室,基于S语言开发的商业软件S-Plus,可以方便的编写函数、建立模型,具有良好的扩展性,在国外学术界应用很广。但是由于商业性特征,其软件价格昂贵。

1995年由新西兰Auckland大学统计系教授Robert Gentleman和他的同事Ross Ihaka,基于S语言的源代码,编写了一能执行S语言的软件,并将该软件的源代码全部公开,这就是R软件,因为主要编写的两位科学家名字首字母都是R,因此其命令统称为R语言。他们就是“R语言之父”。

有趣的是,两位“R语言之父”此后发展轨迹并不相似。 Ross于2017 年退休,此前一直担任新西兰Auckland大学统计学副教授。 Robert则从Auckland统计学教授慢慢变成了生物信息学家。2001年,Robert开始研究Bioconductor项目,以促进生物信息学和计算生物学开源工具的开发。2009年,Robert加入Genentech生物技术公司,担任生物信息学和计算生物学高级主管,同年他编写了一本书《R programming for bioinformatics》。2015年,Robert 加入23andMe,担任计算生物学副总裁,如今他专注于探索23andMe数据库中的人类遗传和性状数据如何用于鉴定新的疾病治疗方法。

23andMe公司由Linda Avey,Paul Cusenza和Anne Wojcicki于2006 年创立,旨在为个人消费者提供基因测试及相应服务,以正常人类细胞中的23对染色体命名,23andMe是第一家为提供祖源分析的常染色体DNA检测的公司。

23andMe基于唾液的直接面向消费者(DTC)的基因检测业务在2008 年被时代杂志评为“年度发明” 。2013年11月,因为基因检测报告中遗传疾病预测未得到充分临床经验验证等争议问题,FDA命令23andMe停止在美国销售其唾液收集试剂盒和个人基因组服务(PGS)。此后,23andMe开始扩宽海外市场,并停止提供健康相关的基因报告。经过几年的市场调研,23andMe验证了部分健康相关基因检测的准确性。2017年4月,FDA批准了其公司包括迟发性阿尔茨海默病,帕金森病等在内的10项基因检测申请。2018年3月,FDA批准了与乳腺癌相关的基因突变检测申请。

目前,国内主流的基因检测产品Wegen和23魔方都学习了23andMe的经验,甚至说模仿了23andMe的产品。

Last updated