重生之我在剑桥大学学习单细胞RNA-seq分析——3. 单细胞分析中的R/Bioconductor简介(3)

3.10 S4对象
S3系统允许创建行为依赖于其第一个参数的类的函数,但不考虑其他参数。另外,S3不允许自定义数据结构,S3系统中使用的变量是单一类型向量或列表。S4系统可以解决这些问题。S4系统与S3的主要区别在于,在S4中每个类都有正式定义,描述该类的对象中存储了什么数据(在S3中您可以将任何类分配给任何变量)。数据存储在具有名称和指定类型的插槽(slots)中,需要指定插槽来创建新类。
现在我们可以创建此类的变量:

> setClass("Person", 
  slots = c(
    name = "character", 
    age = "numeric"
  )
)
> john = new("Person", name = "John Smith", age = 30)
> class(john)
[1] "Person"
attr(,"package")
[1] ".GlobalEnv"
> typeof(john)
[1] "S4"
> john
An object of class "Person"
Slot "name":
[1] "John Smith"

Slot "age":
[1] 30

通常,槽可以通过特定函数访问和修改。对于我们上面指定的Person类,可以使用函数name访问name。但是R允许使用运算符@直接访问插槽:

> john@name
[1] "John Smith"
> slotNames(john)
[1] "name" "age" 
> slot(john,'age')
[1] 30
> john@age
[1] 30

3.11 更多信息
可以在交互式会话中输入?function来获取与这些数据类型相关的任何R命令的更多信息。
3.12 整洁数据(Tidy Data)
3.12.1 什么是整洁数据
整洁数据是一个由Hadley Wickham(Wickham, 2014)定义的概念。整洁数据具有以下三个特征:

  1. 每列代表一个变量。
  2. 每行代表一个观测。
  3. 每个单元格代表一个值。

以下是一些整洁数据的示例:

> data.frame(Students=c("Mark", "Jane", "Mohammed", "Tom", "Celia"), 
             Subject=c("Maths", "Biology", "Physics", "Maths", "Computing"), 
             Years=c(1,2,3,2,3), 
             Score=c(5,6,4,7,9))
  Students   Subject Years Score
1     Mark     Maths     1     5
2     Jane   Biology     2     6
3 Mohammed   Physics     3     4
4      Tom     Maths     2     7
5    Celia Computing     3     9

以下是一些混乱数据的示例:

> data.frame(Students=c("Matt", "Matt", "Ellie", "Ellie", "Tim", "Tim", "Louise", "Louise", "Kelly", "Kelly"), 
             Sport=c("Tennis","Tennis", "Rugby", "Rugby","Football", "Football","Swimming","Swimming", "Running", "Running"), 
             Category=c("Wins", "Losses", "Wins", "Losses", "Wins", "Losses", "Wins", "Losses", "Wins", "Losses"), 
             Counts=c(0,1,3,2,1,4,2,2,5,1))
   Students    Sport Category Counts
1      Matt   Tennis     Wins      0
2      Matt   Tennis   Losses      1
3     Ellie    Rugby     Wins      3
4     Ellie    Rugby   Losses      2
5       Tim Football     Wins      1
6       Tim Football   Losses      4
7    Louise Swimming     Wins      2
8    Louise Swimming   Losses      2
9     Kelly  Running     Wins      5
10    Kelly  Running   Losses      1

任务1:杂乱的数据在哪些方面是不整洁的?我们如何才能使杂乱的数据变得整洁?
整洁的数据通常比不整洁的数据更容易处理,特别是如果你使用诸如ggplot之类的包。幸运的是,有包可以让不整洁的数据变得整洁。今天,我们将探讨tidyr包中的几个可用函数,这些函数可用于整理杂乱的数据。如果你有兴趣了解更多关于整理数据的信息,我们推荐你阅读Garrett Grolemund和Hadley Wickham合著的《R for Data Science》。电子版可在此处获取:http://r4ds.had.co.nz/
上面的杂乱数据之所以杂乱,是因为两个变量(WinsLosses)存储在一列(Category)中。这是数据杂乱的常见原因。为了整理这些数据,我们需要将WinsLosses分成列,并将Counts中的值存储在这些列中。tidyverse包中有一个函数可以执行此操作。该函数名为spread,它接受两个参数,keyvalue。将包含多个变量的列的名称传递给key,将包含多个变量的值的列的名称传递给value

> library(tidyverse)
> sports<-data.frame(Students=c("Matt", "Matt", "Ellie", "Ellie", "Tim", "Tim", "Louise", "Louise", "Kelly", "Kelly"), 
                     Sport=c("Tennis","Tennis", "Rugby", "Rugby","Football", "Football","Swimming","Swimming", "Running", "Running"), 
                     Category=c("Wins", "Losses", "Wins", "Losses", "Wins", "Losses", "Wins", "Losses", "Wins", "Losses"), 
                     Counts=c(0,1,3,2,1,4,2,2,5,1))
> sports
   Students    Sport Category Counts
1      Matt   Tennis     Wins      0
2      Matt   Tennis   Losses      1
3     Ellie    Rugby     Wins      3
4     Ellie    Rugby   Losses      2
5       Tim Football     Wins      1
6       Tim Football   Losses      4
7    Louise Swimming     Wins      2
8    Louise Swimming   Losses      2
9     Kelly  Running     Wins      5
10    Kelly  Running   Losses      1
> spread(sports, key=Category, value=Counts)
  Students    Sport Losses Wins
1    Ellie    Rugby      2    3
2    Kelly  Running      1    5
3   Louise Swimming      2    2
4     Matt   Tennis      1    0
5      Tim Football      4    1

任务2:下面定义的数据框foods很乱。找出原因并使用spread()来整理它。

foods<-data.frame(student=c("Antoinette","Antoinette","Taylor", "Taylor", "Alexa", "Alexa"), 
                  Category=c("Dinner", "Dessert", "Dinner", "Dessert", "Dinner","Dessert"), 
                  Frequency=c(3,1,4,5,2,1))

数据混乱的另一种常见情况是列是值而不是变量。例如,下面的数据框显示了一些学生在5月和6月的测试中获得的百分比。数据很混乱,因为5月和6月的列是值,而不是变量。

percentages<-data.frame(student=c("Alejandro", "Pietro", "Jane"), 
                        "May"=c(90,12,45), 
                        "June"=c(80,30,100))

tidyverse包中有一个函数可以解决这个问题。gather()将列的名称、keyvalue作为参数。这一次,key是以列名作为值的变量的名称,value是分布在多列中的值的变量名称。

> gather(percentages, "May", "June", key="Month", value = "Percentage")
    student Month Percentage
1 Alejandro   May         90
2    Pietro   May         12
3      Jane   May         45
4 Alejandro  June         80
5    Pietro  June         30
6      Jane  June        100

这些例子与单细胞RNA-seq分析没有太大关系,但旨在帮助说明整洁和不整洁数据的特征。如果您的数据以整洁的格式存储,您会发现分析单细胞RNA-seq数据变得更加容易。幸运的是,我们通常用于单细胞RNA-seq分析的数据结构鼓励以整洁的方式存储数据。
3.12.2 什么是Rich Data
如果你在Google上搜索“Rich Data”,你会发现这个术语有很多不同的定义。在本课程中,我们将使用“Rich Data”来表示通过组合来自多个来源的信息而生成的数据。例如,您可以通过在R中创建一个对象来制作Rich Data,该对象包含单细胞RNA测序实验中跨细胞的基因表达矩阵,还包含有关如何进行实验的信息。我们将在下面讨论的SingleCellExperiment类的对象就是Rich Data的一个例子。
3.12.3 SingleCellExperiment
SingleCellExperiment(SCE)是一个S4类,用于存储单细胞实验的数据。这包括用于存储和检索峰值信息、每个细胞的降维坐标和尺度因子以及基因和文库的常用元数据的专门方法。
可以使用其构造函数创建此类的对象:

> library(SingleCellExperiment)
> counts <- matrix(rpois(100, lambda = 10), ncol=10, nrow=10)
> rownames(counts) <- paste("gene", 1:10, sep = "")
> colnames(counts) <- paste("cell", 1:10, sep = "")
> sce <- SingleCellExperiment(
    assays = list(counts = counts),
    rowData = data.frame(gene_names = paste("gene_name", 1:10, sep = "")),
    colData = data.frame(cell_names = paste("cell_name", 1:10, sep = ""))
)
> sce
class: SingleCellExperiment 
dim: 10 10 
metadata(0):
assays(1): counts
rownames(10): gene1 gene2 ... gene9 gene10
rowData names(1): gene_names
colnames(10): cell1 cell2 ... cell9 cell10
colData names(1): cell_names
reducedDimNames(0):
altExpNames(0):

SingleCellExperiment中,用户可以为检测条目分配任意名称。为了协助包之间的互操作性,作者对特定类型数据的名称提供了一些建议:

  • counts:原始计数数据,例如特定基因的read数或转录本数。
  • normcounts:与原始计数具有相同尺度的标准化值。例如,计数除以以1为中心的细胞特异尺度因子。
  • logcounts:对数转换计数或类似计数的值。在大多数情况下,定义为对数转换的normcounts,例如,使用以2为底的对数和伪计数1。
  • cpm:每百万计数。这是每个细胞中每个基因的read计数,除以每个细胞的文库大小(以百万为单位)。
  • tpm:每百万转录本数。这是每个细胞中每个基因的转录本数除以该细胞中的转录本总数(以百万为单位)。

每个建议的名称都有一个适当的访问/修改方法,以方便操作SingleCellExperiment。例如,我们可以取counts槽,对其进行标准化,然后将其分配给normcounts

> normcounts(sce) <- log2(counts(sce) + 1)
> sce
class: SingleCellExperiment 
dim: 10 10 
metadata(0):
assays(2): counts normcounts
rownames(10): gene1 gene2 ... gene9 gene10
rowData names(1): gene_names
colnames(10): cell1 cell2 ... cell9 cell10
colData names(1): cell_names
reducedDimNames(0):
altExpNames(0):
> dim(normcounts(sce))
[1] 10 10
> head(normcounts(sce))
         cell1    cell2    cell3    cell4    cell5    cell6    cell7    cell8
gene1 2.584963 3.321928 3.906891 3.584963 3.807355 2.807355 3.807355 3.584963
gene2 3.584963 3.459432 4.392317 3.584963 2.321928 3.459432 3.169925 3.000000
gene3 3.700440 3.807355 4.087463 3.700440 3.000000 3.459432 3.000000 3.169925
gene4 3.459432 3.321928 3.459432 3.000000 3.584963 3.584963 3.169925 3.906891
gene5 3.321928 3.459432 2.807355 4.000000 3.321928 3.584963 3.321928 3.807355
gene6 3.584963 2.000000 3.584963 3.584963 3.169925 3.459432 2.807355 3.700440
         cell9   cell10
gene1 3.584963 3.321928
gene2 3.584963 3.321928
gene3 3.584963 2.321928
gene4 3.584963 3.700440
gene5 3.584963 2.807355
gene6 3.459432 2.584963

3.12.4 scater
scater是一个用于单细胞RNA测序分析的R包(McCarthy等,2017)。该软件包包含几种有用的方法,用于进一步下游分析之前的质量控制、可视化和数据预处理。
scater具有以下功能:

  • 自动计算QC指标
  • 使用伪比对对read数据进行转录本定量
  • 数据格式标准化
  • 丰富的可视化功能,可用于探索性分析
  • 无缝集成到Bioconductor
  • 简单的标准化方法

我们强烈建议所有单细胞RNA-seq分析都使用scaterscater是本课程第一部分的基础。
如下图所示,scater将帮助您对表达矩阵进行质量控制、过滤和标准化。请记住,此图代表了scater的原始版本,其中使用了SCESet类。在最新版本中,此图仍然正确,只是SCESet可以用SingleCellExperiment类替代。

往期内容:
重生之我在剑桥大学学习单细胞RNA-seq分析——2. scRNA-Seq原始测序数据处理(1)
重生之我在剑桥大学学习单细胞RNA-seq分析——2. scRNA-Seq原始测序数据处理(2)
重生之我在剑桥大学学习单细胞RNA-seq分析——3. 单细胞分析中的R/Bioconductor简介(1)
重生之我在剑桥大学学习单细胞RNA-seq分析——3. 单细胞分析中的R/Bioconductor简介(2)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容