内容

今天我们将介绍癌症研究中常用的统计概念和测试。我们将访问的数据集是ALL表达式数据的子集,我们在第一天的材料中使用了这些数据集的患者信息。除了这些信息,我们还将访问1000个相关的表达微阵列特征,这些特征在患者样本中呈现出最高的方差。数据以二进制格式保存,以减小文件大小。

1单变量分析

下面将继续探讨本课程早期的“ALL”表型数据。像以前一样,从加载数据开始。

path <- file.choose() #查找ALLphenoData.tsv
Stopifnot (file.exists(path)) pdata <- read.csv(path)

1.1描述性统计

让我们仔细看看病人的信息pdata对象:

中位数(pdata时代美元)
## [1] na

的值NA出现是因为一些pdata美元时代值为NA。我们可以通过询问来验证这一点R如果有NA值

任何(is.na (pdata年龄)美元)
##[1]真
anyNA(pdata$age) #相同,但更有效
##[1]真

查阅帮助页?值建议一个解决方案-指定参数na.rm = TRUE.探索年龄的其他方面,比如range ()而且分位数()

年龄中位数(pdata $ na.rm = TRUE)
29
范围(pdata时代,美元na.rm = TRUE)
## [1] 5 58
分位数(pdata $年龄,na.rm = TRUE)
## 0% 25% 50% 75% 100% ## 5.0 19.0 29.0 45.5 58.0

一些简单的病人年龄图-注意嵌套函数!

plot(pdata$age) plot(sort(pdata$age)) sortedAge = sort(pdata$age)

直方图及其显示选项:

Hist (pdata$age, br=25)

交叉表使用公式描述它们所呈现的数据之间的关系:

xtabs(~sex, data=pdata, exclude=NA)
##性## F M ## 42 83
xtabs(~性+缓解,数据=pdata,排除=NA)
##缓解##性CR ## F 27 7 ## M 71 8

1.2t

使用图()图中女性和男性年龄的分布pdata数据集。

图(年龄~性别,pdata)

看起来女性的平均年龄比男性大。使用t.test ()为了找出答案。

T.test(年龄~性别,pdata)
## ## Welch Two样本t检验## ##数据:按性别划分的年龄t = 1.6034, df = 79.88, p值= 0.1128 ##替代假设:均值的真实差异不等于0 ## 95%置信区间:## -1.022660 9.504142 ##样本估计:## F组的均值M组的均值35.16667 30.92593

查看帮助页t.test ()

t.test ?

这些额外的论点是什么t.test ()?举个例子,这是什么意思var.equal论点吗?为什么有79.88个自由度?

t.test(年龄~性别,pdata, var.equal=TRUE)
## ##两个样本t检验## ##数据:年龄按性别的t = 1.6266, df = 121, p值= 0.1064 ##替代假设:均值的真实差异不等于0 ## 95%置信区间:## -0.9207109 9.4021924 ##样本估计:## F组均值在M组的35.16667 30.92593

1.3线性模型

t检验也可以被视为方差分析(ANOVA);方差分析是线性模型的一种形式。使用lm ()拟合一个描述年龄随性别变化的线性模型;的方差分析()函数总结了线性模型在一个可能更熟悉的方差分析表。

(fit <- lm(年龄~性别,pdata))
## ##调用:## lm(公式=年龄~性别,数据= pdata) ## ##系数:##(截距)sexm# # 35.167 -4.241
方差分析(适合)
##方差分析表## ##响应:年龄## Df Sum Sq Mean Sq F value Pr(>F) ##性别1 497.4 497.41 2.6459 0.1064 ##残差121 22747.4 187.99

在线性模型中做了什么样的假设,例如,关于方差相等?尝试策划适合;这些数字想告诉你什么?

情节(适合)

适合是一个例子吗R对象.找出它是班级

类(适合)
##[1]“lm”

情节是一个例子吗R通用的;它有不同的方法为不同类型的对象实现。使用方法()查看可用的方法

方法(图)
##[1]情节。HoltWinters *情节。TukeyHSD *情节。Acf * plot.data.frame* ## [5] plot.decomposed.ts* plot.default plot.dendrogram* plot.density* ## [9] plot.data.frameecdf阴谋。*情节因素。公式*情节。函数## [13] plot.hclust* plot.histogram* plot.isoreg* plot.lm* ## [17] plot.medpolish* plot.mlm* plot.ppr* plot.prcomp* ## [21] plot.princomp* plot.profile.nls* plot.raster* plot.spec* ## [25] plot.stepfun plot.stl* plot.table* plot.ts ## [29] plot.tskernel* ## see '?methods' for accessing help and source code

的帮助页情节通用的,lm方法

plot.lm ?

拟合模型可用于其他功能,例如预测新数据的值。构造一个data.frame使用单列与价值观“M”而且“F”.方法,请参阅帮助页predict.lm方法,并计算拟合模型对男性和女性的期望值。

df = data.frame(sex=c("F", "M"))
# 1 2 ## 35.16667 30.92593

中预测值对应于什么t.test ()?使用系数()提取拟合模型的系数。

系数(适合)
##(拦截)sexM ## 35.166667 -4.240741

解释(拦截)而且sexM以女性和男性年龄表示的系数。

1.4卡方测试

从这篇文章pdata“虽然染色体易位和分子重排在t系ALL中相对较少,但这些事件在b系ALL中普遍发生,反映了不同的转化机制”。让我们来研究一下这个说法。

相关的数据列总结为

总结(pdata [c(“转基因”、“cyto.normal”)))
## BT cyto。正常## B2:36模式:逻辑## B3:23 FALSE:69 ## B1:19 TRUE:24 ## T2:15 NA's:35 ## B4:12 ## T3:10 ##(其他):13

化简英国电信创建一个新列BT.通过创建substr ()由每一项的第一个字母组成的原列的Ing,并将这个向量转化为a因素().将其分配给一个新的列名

pdata$BT <- substr(pdata$BT, 1,1))

交叉列出数据

xtabs(~ BorT + cyto。正常,pdata)
# #阶段。正常##波特假真## B 56 17 ## T 13 7

这些数据与分子重排在b系ALL中更为常见的说法定性一致。我们用卡方检验

chisq。测试(pdata圆粒金刚石美元,pdata cyto.normal美元)
## ## Pearson的卡方检验与Yates的连续性修正## ##数据:pdata$BorT和pdata$cyto。x平方= 0.59622,df = 1, p值= 0.44

解释结果。文档中的附加参数呢chisq.test ?

2多元分析:机器学习

我们研究的128个样本来自微阵列实验。微阵列由“探针”组成,它对基因的表达水平进行筛选。在我们正在研究的实验中,128个样本中每个样本上都测量了12625个探针。通过微阵列分析估计的原始表达水平需要大量的预处理,我们将使用的数据已经预处理过。

首先在磁盘上查找表达式数据文件。

path <- file.choose() #查找ALL-expression.csv stopifnot(file.exists(path))

数据以“逗号分隔值”格式存储,每个探针集占用一行,该探针集中每个样本的表达式值用逗号分隔。使用以下命令输入数据read.csv ().这里有三个挑战:

  1. 行名出现在数据的第一列中。告诉R通过添加参数来实现row.names = 1read.csv ()
  2. 默认情况下,R检查列名是否看起来像数字,而是我们的列名看起来像数字。使用论证check.colnames = FALSE习惯R的违约。
  3. read.csv ()返回一个data.frame.我们可以用data.frame来处理我们的数据,但实际上矩阵()-这些列是相同类型的,测量相同的东西。使用as.matrix ()强迫data.frame输入a矩阵
exprs <- read.csv(path, row.names=1, check.names=FALSE)

我们还将使用描述样本的数据

path <- file.choose() #查找ALL-phenoData.csv stopifnot(file.exists(path)) pdata <- read.csv(path, row.names=1)

我们将添加一列pdata,由英国电信列,表示样本是b细胞还是t细胞ALL。

pdata$BT <- factor(substr(pdata$BT, 1,1)) xtabs(~ BT + BT, pdata)
## BT ##波特B B1 B2 B3 B4 T T1 T2 T3 T4 ## B 5 19 36 23 12 0 0 0 0 0 0 ## T 0 0 0 0 5 1 15 10 2

下面的一些结果涉及到图形,选择漂亮而实用的颜色很方便。我们使用RColorBrewer包;看到colorbrewer.com

图书馆(RColorBrewer)发散<- brewer。pal(11, "RdBu") highlight <- brewer。关于我校“pal (3) [1:2]

“divergent”是一个颜色向量,从红色(负)到蓝色(正)。' highlight '是一个长度为2,浅绿色和深绿色的向量。

有关更多选项,请参见RColorBrewer ?和查看预定义的调色板display.brewer.all ()

2.1初步勘探和清理

验证我们有一个合适的矩阵类()而且昏暗的()正;在数据的前五行和前五列取峰值。

类(exprs)
##[1]“矩阵”
暗(exprs)
## [1] 12625 128
exprs [1:5, 1:5)
## 100_at 7.597323 7.479445 7.384684 7.905312 ## 1001_at 5.046194 4.932537 4.799294 4.922627 4.844565 ## 1002_f_at 3.900466 4.208155 3.886169 4.206798 3.416923 ## 1003_s_at 5.903856 6.169024 5.860459 6.116890 5.687997 ## 1004_at 5.925260 5.912780 5.893209 6.170245 5.615210

我们将使用数据的子集,特别是在样本中显示最大方差的1000个探针集。单行方差可计算为

var (exprs [1])
## [1] 0.06768013

方法可以计算每行之间的方差应用()函数。第一个参数是我们想要总结的矩形数据结构,第二个参数是维度(1行;2对于列),我们想对其进行总结,第三个参数是我们想应用于每一行或每列的函数。使用可视化的探测集方差分布嘘(),可能是在转换后的数据上。

V <- apply(expr, 1, var) hist(√(V))

使用订单(v,减少= TRUE)如何确定元素的v应该选择,以便它们从高到低的顺序,直观地验证值实际上是从高到低的顺序…

o <- order(v,递减=TRUE) plot(根号(v[o]))

使用头()选择变量最多的1000个探测集的索引,并创建一个子集exprs矩阵包含这些探测集

exps1000 <- exprs[头(o, 1000),]
  1. 类运动:使用应用()exprs1000为了验证我们似乎有1000个最可变的探测集。

2.2集群:dist ()而且hclust ()

我们想了解数据中是否存在模式,例如样本之间整体表达模式的一致性差异。一种方法是分层聚类

计算样本间的欧氏距离dist ()t ()ranspose的exprs1000(查看? dist对于其他距离度量)。

D <- dist(t(express1000))

使用hclust ()对数据进行聚类,和图()为了可视化集群。

情节(hclust (d))

的列进行标记具有丰富的信息exprs1000ALL子类型(例如B1, B2, T1等)。首先,使用相同的()要验证colnames ()exprs1000是一样的rownames ()pdata

相同的(colnames (exprs1000) rownames (pdata))
##[1]真

现在替换的列名exprs1000pdata BT美元,并重复聚类。

colnames(exprs1000) <- pdata$BT plot(hclust(dist(t(exprs1000))))

Colnames (exprs1000) <- rownames(pdata)

很明显,B细胞ALL和t细胞ALL的整体基因表达模式不同。

支持树状图的数据hclust ()可以可视化为热图().在这里,我们计算每个样本之间的相关矩阵;在热图的行和列排序时,我们将使用它作为距离度量的基础。

D <- dist(t(express1000))

以下热图()命令执行距离的层次聚类,并添加一个颜色条来指示样本来自B或T谱系样本。

color <- highlight[pdata$BorT]热图(as.matrix(d), ColSideColor=color, col=divergent, symm=TRUE)

2.3集群:cmdscale ()以及其他降维方法

我们已经在1000个维度上描述了我们的128个样本。层次聚类表明在这种高维数据中存在某种模式。我们可以使用许多统计技术来有效地降低数据的维度。降维表示可以用于可视化或下游分析。

一种降低数据维数的方法是经典的多维定标(原理坐标分析)。其思想是对不相似度进行测量(如上面计算的距离矩阵),并将其缩减为一组点(例如,在二维空间中),使得点之间的距离近似等于不相似度。这很容易实现R,使用cmdscale ()函数。

MDS <- cmdscale(dist(t(express1000))) plot(MDS, col=color)

mds是一个128 x 2的矩阵,列可以用作1000个表达式值的降维替换。

主成分分析是一种类似于可视化和降维下游分析的方法;看到prcomp ()

2.4分类:然而,()

分类(“监督机器学习”)根据与一组“训练”样本的相似程度将“测试”样本分配到一个组中。分类有很多种。然而,(k个最近邻居)分类将测试样本分配给它的k个最近邻居中的多数投票。然而,()类中定义了其他常见的分类符包,所以我们先把它加到我们的R会话。

库(类)

我们将从创建一个训练集开始。我们将选择' B '个体的前一半和' T '个体的前一半作为成员。首先,我们可以使用seq_along ()

seq_along (pdata圆粒金刚石美元)
# #[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日# #[24]24日25日26日27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 # # [47]47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 # # [70]70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 # # [93]93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 # # [116]116 117 118 119 120 121 122 123 124 125 126 127 128

可以使用。将这些值分成组(整数列表)split ()

idxByType <- split(seq_along(pdata$BorT), pdata$BorT
# # $ B # #[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 # # 33 [33]34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 # # [65]65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 # # # # # # 95 T [1] 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 # # [25] 120 121 122 123 124 125 126 127 128

我们可以问每个元素的个数idxByType通过提取元素并使用长度()功能,例如,长度(idxByType [[B]]).我们可以用头()选择元素的前半部分

Bidx <- idxByType[["B"]] BTrainIdx <- head(Bidx, length(Bidx) / 2)

T也是一样:

Tidx <- idxByType[["T"]] TTrainIdx <- head(Tidx, length(Tidx) / 2)

有两件有趣的事情需要注意,这有助于我们扩大我们的知识R

  1. 注意,我们对B和T索引应用了相同的操作序列。R让我们写一个函数来捕获这个重复的操作

    firstalf <- function(x) {head(x, length(x) / 2)}

    我们可以证明这是可行的

    库(idxByType [[B]])
    ## [1] 12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ## [33] 33 34 35 36 37 38 39 40 41 42 43 44 45 46 46 47
    库(idxByType [[T]])
    ## [1] 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
  2. 我们想把这个函数应用到列表的每个元素上idxByType.这可以用拉普兰人(),其中第一个参数是一个向量,第二个参数是我们想要应用的函数

    trainIdx <- lapply(idxByType, firstalf) trainIdx . trainIdx . trainIdx . trainIdx . trainIdx . trainIdx . trainIdx . trainIdx
    ## $ b ## [1] 12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ## [33] 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ## ## $ t ## [1] 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

好的,让我们从每组的前一半组成我们的训练集cbind ()创建一个单独的训练个体矩阵

Bhalf <- exprs1000[, trainIdx[["B"]]] Thalf <- exprs1000[, trainIdx[["T"]]] train <- cbind(Bhalf, Thalf)

我们的测试集是不包括在训练集中的个体。选择这些人的一种方法是写一份简历后半叶()函数;另一种方法是子集exprs1000以包含不在中的列火车

测试<- express1000 [, !Colnames (exprs1000) %in% Colnames (train)]

我们需要知道训练集和测试集的分类

cl_train <- pdata[colnames(train), "BorT"] cl_test <- pdata[colnames(test), "BorT"]

然而,()使用训练集和测试集以及训练集的已知分类调用。这个论点k要考虑的是最近邻居的数量;默认为k = 1.返回值是每个测试样本的估计分类

Cl_test_est <- knn(t(test), t(test), cl_train)

分类器表现如何的表征是“混淆矩阵”,它在交叉表格中总结了测试个体的已知与估计分类

Xtabs (~cl_test + cl_test_est)
17 . B T ## B 48 0 ## T 0

在这里,分类器执行得非常好——没有不正确的(非对角线)赋值。

我们一直在使用已知数据来创建分类器,然后评估它的性能。使用一半的B样本和一半的T样本,并将每个组的前一半纳入“训练”组的决定是任意的,事实证明,更好的策略是“保留一个”交叉验证。它的工作原理是使用训练组中除了一个样本(例如,第一个样本)之外的所有样本,然后对遗漏的样本进行分类。然后重复第二个,第三个,……样本。R为KNN实现此功能knn.cv ()函数(同样使用默认值k = 1最近的邻居)。

knn_loo <- knn.cv(t(exprs1000), pdata$ port) xtabs(~pdata$ port + knn_loo)
## knn_loo ## pdata$BorT B t# # B 95 0 ## T 0 33

作为练习,使用knn.cv ()开发t细胞亚型的分类器;探究不同价值观的后果k.以下是该方法的概述:

  1. 仅使用T细胞类型创建表达和表型数据的子集;记得使用因素()删除未使用的级别

    keep <- pdata$BT == "T" exprT <- exprs1000[, keep] classT <- factor(pdata$BT[keep])
  2. 使用knn.cv ()要执行交叉验证,和xtabs ()总结一下混淆矩阵。解释混淆矩阵。

    xtabs(~classT + knn.cv(t(exprT), classT))
    ## knn.cv(t(exprT), classT) ## classT t T1 T2 T3 T4 ## t 0 0 4 1 0 ## T1 0 0 1 0 0 0 0 0 ## T2 5 0 4 3 3 ## T3 1 0 2 6 1 ## T4 0 0 0 1 1 1
  3. 的不同值进行实验k.你能解释结果吗k的统计原理精度而且精度

3.经验教训

  1. 有非常灵活的处理数据的方法,例如,1维和2维的子集,访问data.frame中的列或者用二维子集,创建因素()年代,等等。

  2. 单变量统计函数,例如:意思是()中位数()t.test ()lm ()chisq.test ()

  3. 多元统计函数,例如:dist ()hclust ()热图()然而,()knn.cv ()

  4. 包提供专门的功能,例如,RColorBrewer,(类)[]。

  5. 内置函数可以处理矩阵的行或列(应用())或列表元素(拉普兰人();另请参阅酸式焦磷酸钠()vapp ()宾州()tappyl ()).

  6. 我们可以编写自己的函数!

  7. 帮助系统是我们的朋友!