>islands
里面根本没有你的变量Sepal.Length和Islands,怎么画图。
你可以看看手册上的范例:
boxplot(count ~ spray, data = InsectSprays, col = "lightgray")
打开数据库 InsectSprays
>InsectSprays
可以看到列名就是count和spray,就是以spray为level,画count的箱线图
“参考网址1”中提到如果只是对整数运算(运算过程和结果都只使用整数),没有必要使用“double”(8 byte),而应该用更小的“integer”(4 byte)。使用storage.mode(x)查看对象存数的模式,storage.mode(x) <- 进行赋值;使用format(object.size(a), units = 'auto')查看对象占用的内存空间(此处有疑问,即在R中每个integer到底占用了多大的空间?)。需要解释gc()函数,可以查看内存使用情况。同样,在清除了大的对象之后,使用gc()以释放内存使用空间。
李航在”参考网址2“中提到,对于大矩阵的操作,尽量避免使用cbind和rbind之类,因为这会让内存不停地分配空间。“对于长度增加的矩阵,尽量先定义一个大矩阵,然后逐步增加”和“注意清除中间对象”。
使用bigmemory家族:bigmemory, biganalytics, synchronicity, bigtabulate and bigalgebra, 同时还有
biglm。
bigmemory package的使用:
1. 建立big.memory对象
bigmemory采用C++的数据格式来“模仿”R中的matrix。
编写大数据格式文件时候,可以先建立filebacked.big.matrix
big.matrix(nrow, ncol, type = options()$bigmemory.default.type, init = NULL, dimnames = NULL, separated = FALSE, backingfile = NULL, backingpath = NULL, descriptorfile = NULL, shared = TRUE)
filebacked.big.matrix(nrow, ncol, type = options()$bigmemory.default.type, init = NULL, dimnames = NULL, separated = FALSE, backingfile = NULL, backingpath = NULL, descriptorfile = NULL)
as.big.matrix(x, type = NULL, separated = FALSE, backingfile = NULL, backingpath = NULL, descriptorfile = NULL, shared=TRUE)
使用注意:
big.matrix采用两种方式储存数据:一种是big.matrix默认的方式,如果内存空间比较大,可以尝试使用;另外一种是filebacked.big.matrix,这种储存方法可能会备份文件(file-backings),而且需要descriptor file;
“init”指矩阵的初始化数值,如果设定,会事先将设定的数值填充到矩阵中;如果不设置,将处理为NA
"type"是指在big.matrix中atomic element的储存格式,默认是“double”(8 byte),可以改为“integer”(4 byte), "short"(2 byte) or "char"(1 byte)。注意:这个包不支持字符串的储存,type = "char"是指ASCII码字母。
在big.matrix非常大的时候,避免使用rownames和colnames(并且bigmemory禁止用名称访问元素),因为这种做法非常占用内存。如果一定要改变,使用options(bigmemory.allow.dimnames=TRUE),之后colnames, rownames设置。
直接在命令提示符后输入x(x是一个big matrix),将返回x的描述,不会出现所有x中所有内容。因此,注意x[ , ](打印出矩阵全部内容);
如果big.matrix有很多列,那么应该将其转置后储存;(不推荐)或者将参数“separated”设置为TRUE,这样就将每一列分开储存。否则,将用R的传统方式(column major的方式)储存数据。
如果建立一个filebacked.big.matrix,那么需要指定backingfile的名称和路径+descriptorfile。可能多个big.matrix对象对应唯一一个descriptorfile,即如果descriptorfile改变,所以对应的big.matrix随之改变;同样,decriptorfile随着big.matrix的改变而改变;如果想维持一种改变,需要重新建立一个filebacked.big.matrix。attach.big.matrix(descriptorfile or describe(big.matrix))函数用于将一个descriptorfile赋值给一个big.matrix。这个函数很好用,因为每次在创建一个filebacked.big.matrix后,保存R并退出后,先前创建的矩阵会消失,需要再attach.big.matrix以下
2. 对big.matrix的列的特定元素进行条件筛选
对内存没有限制;而且比传统的which更加灵活(赞!)
mwhich(x, cols, vals, comps, op = 'AND')
x既可以是big.matrix,也可以是传统的R对象;
cols:行数
vals:cutoff,可以设定两个比如c(1, 2)
comps:'eq'(==), 'neq'(!=), 'le'(<), 'lt'(<=), 'ge'(>) and 'gt'(>=)
op:“AND”或者是“OR”
可以直接比较NA,Inf和-Inf
3.bigmemory中其他函数
nrow, ncol, dim, dimnames, tail, head, typeof继承base包
big.matrix, is.big.matrix, as.big.matrix, attach.big.matrix, describe, read.big.matrix, write.big.matrix, sub.big.matrix, is.sub.big.matrix为特有的big.matrix文件操作;filebacked.big.matrix, is.filebacked(判断big.matrix是否硬盘备份) , flush(将filebacked的文件刷新到硬盘备份上)是filebacked的big.matrix的操作。
mwhich增强base包中的which, morder增强order,mpermute(对matrix中的一列按照特定序列操作,但是会改变原来对象,这是为了避免内存溢出)
big.matrix对象的copy使用deepcopy(x, cols = NULL, rows = NULL, y = NULL, type = NULL, separated = NULL, backingfile = NULL, backingpath = NULL, descriptorfile = NULL, shared=TRUE)
biganalytics package的使用
biganalytics主要是一些base基本函数的扩展,主要有max, min, prod, sum, range, colmin, colmax, colsum, colprod, colmean, colsd, colvar, summary, apply(只能用于行或者列,不能用行列同时用)等
比较有特色的是bigkmeans的聚类
剩下的biglm.big.matrix和bigglm.big.matrix可以参考Lumley's biglm package。
bigtabulate package的使用
并行计算限制的突破:
使用doMC家族:doMC, doSNOW, doMPI, doRedis, doSMP和foreach packages.
foreach package的使用
foreach(..., .combine, .init, .final=NULL, .inorder=TRUE, .multicombine=FALSE, .maxcombine=if (.multicombine) 100 else 2, .errorhandling=c('stop', 'remove', 'pass'), .packages=NULL, .export=NULL, .noexport=NULL, .verbose=FALSE)
foreach的特点是可以进行并行运算,如在NetWorkSpace和snow?
%do%严格按照顺序执行任务(所以,也就非并行计算),%dopar%并行执行任务
...:指定循环的次数;
.combine:运算之后结果的显示方式,default是list,“c”返回vector, cbind和rbind返回矩阵,"+"和"*"可以返回rbind之后的“+”或者“*”
.init:.combine函数的第一个变量
.final:返回最后结果
.inorder:TRUE则返回和原始输入相同顺序的结果(对结果的顺序要求严格的时候),FALSE返回没有顺序的结果(可以提高运算效率)。这个参数适合于设定对结果顺序没有需求的情况。
.muticombine:设定.combine函数的传递参数,default是FALSE表示其参数是2,TRUE可以设定多个参数
.maxcombine:设定.combine的最大参数
.errorhandling:如果循环中出现错误,对错误的处理方法
.packages:指定在%dopar%运算过程中依赖的package(%do%会忽略这个选项)。
getDoParWorkers( ) :查看注册了多少个核,配合doMC package中的registerDoMC( )使用
getDoParRegistered( ) :查看doPar是否注册;如果没有注册返回FALSE
getDoParName( ) :查看已经注册的doPar的名字
getDoParVersion( ):查看已经注册的doPar的version
===================================================
# foreach的循环次数可以指定多个变量,但是只用其中最少?的
>foreach(a = 1:10, b = rep(10, 3)) %do% (a*b)
[[1]]
[1] 10
[[2]]
[1] 20
[[3]]
[1] 30
# foreach中.combine的“+”或者“*”是cbind之后的操作;这也就是说"expression"返回一个向量,会对向量+或者*
>foreach(i = 1:4, .combine = "+") %do% 2
[1] 8
>foreach(i = 1:4, .combine = "rbind") %do% rep(2, 5)
[,1] [,2] [,3] [,4] [,5]
result.122222
result.222222
result.322222
result.422222
>foreach(i = 1:4, .combine = "+") %do% rep(2, 5)
[1] 8 8 8 8 8
>foreach(i = 1:4, .combine = "*") %do% rep(2, 5)
[1] 16 16 16 16 16
=============================================
iterators package的使用
iterators是为了给foreach提供循环变量,每次定义一个iterator,它都内定了“循环次数”和“每次循环返回的值”,因此非常适合结合foreach的使用。
iter(obj, ...):可以接受iter, vector, matrix, data.frame, function。
nextElem(obj, ...):接受iter对象,显示对象数值。
以matrix为例,
iter(obj, by=c('column', 'cell', 'row'), chunksize=1L, checkFunc=function(...) TRUE, recycle=FALSE, ...)
by:按照什么顺序循环;matrix和data.frame都默认是“row”,“cell”是按列依次输出(所以对于“cell”,chunksize只能指定为默认值,即1)
chunksize:每次执行函数nextElem后,按照by的设定返回结果的长度。如果返回结构不够,将取剩余的全部。
checkFunc=function(...) TRUE:执行函数checkFun,如果返回TRUE,则返回;否则,跳过。
recycle:设定在nextElem循环到底(“错误: StopIteration”)是否要循环处理,即从头再来一遍。
以function为例
iter(function()rnorm(1)),使用nextElem可以无限重复;但是iter(rnorm(1)),只能来一下。
更有意思的是对象如果是iter,即test1 <- iter(obj)test2 <- iter(test1),那么这两个对象是连在一起的,同时变化。
==============================================
>a
[,1] [,2] [,3] [,4] [,5]
[1,]159 13 17
[2,]26 10 14 18
[3,]37 11 15 19
[4,]48 12 16 20
>i2 <- iter(a, by = "row", chunksize=3)
>nextElem(i2)
[,1] [,2] [,3] [,4] [,5]
[1,]159 13 17
[2,]26 10 14 18
[3,]37 11 15 19
>nextElem(i2) #第二次iterate之后,只剩下1行,全部返回
[,1] [,2] [,3] [,4] [,5]
[1,]48 12 16 20
>i2 <- iter(a, by = "column", checkFunc=function(x) sum(x) >50)
>nextElem(i2)
[,1]
[1,] 13
[2,] 14
[3,] 15
[4,] 16
>nextElem(i2)
[,1]
[1,] 17
[2,] 18
[3,] 19
[4,] 20
>nextElem(i2)
错误: StopIteration
>colSums(a)
[1] 10 26 42 58 74
>testFun <- function(x){return(x+2)}
>i2 <- iter(function()testFun(1))
>nextElem(i2)
[1] 3
>nextElem(i2)
[1] 3
>nextElem(i2)
[1] 3
>i2 <- iter(testFun(1))
>nextElem(i2)
[1] 3
>nextElem(i2)
错误: StopIteration
>i2 <- iter(testFun(1))
>i3 <- iter(i2)
>nextElem(i3)
[1] 3
>nextElem(i2)
错误: StopIteration
============================================
iterators package中包括
irnorm(..., count);irunif(..., count);irbinom(..., count);irnbinom(..., count);irpois(..., count)中内部生成iterator的工具,分别表示从normal,uniform,binomial,negativity binomial和Poisson分布中随机选取N个元素,进行count次。其中,negative binomial分布:其概率积累函数(probability mass function)为掷骰子,每次骰子为3点的概率为p,在第r+k次恰好出现r次的概率。
icount(count)可以生成1:conunt的iterator;如果count不指定,将从无休止生成1:Inf
icountn(vn)比较好玩,vn是指一个数值向量(如果是小数,则向后一个数取整,比如2.3 -->3)。循环次数为prod(vn),每次返回的向量中每个元素都从1开始,不超过设定 vn,变化速率从左向右依次递增。
idiv(n, ..., chunks, chunkSize)返回截取从1:n的片段长度,“chunks”和“chunkSize”不能同时指定,“chunks”为分多少片段(长度从大到小),“chunkSize”为分段的最大长度(长度由大到小)
iapply(X, MARGIN):与apply很像,MARGIN中1是row,2是column
isplit(x, f, drop=FALSE, ...):按照指定的f划分矩阵
=============================================
>i2 <- icountn(c(3.4, 1.2))
>nextElem(i2)
[1] 1 1
>nextElem(i2)
[1] 2 1
>nextElem(i2)
[1] 3 1
>nextElem(i2)
[1] 4 1
>nextElem(i2)
[1] 1 2
>nextElem(i2)
[1] 2 2
>nextElem(i2)
[1] 3 2
>nextElem(i2)
[1] 4 2
>nextElem(i2)
错误: StopIteration
下游分析
cellranger count 计算的结果只能作为错略观测的结果,如果需要进一步分析聚类细胞,还需要进行下游分析,这里使用官方推荐 R 包(Seurat 3.0)
流程参考官方外周血分析标准流程( https://satijalab.org/seurat/v3.0/pbmc3k_tutorial.html )
Rstudio操作过程:
## 安装seurat
install.packages('Seurat')
## 载入seurat包
library(dplyr)
library(Seurat)
## 读入pbmc数据(文件夹路径不能包含中文,注意“/“的方向不能错误,这里读取的是10x处理的文件,也可以处理其它矩阵文件,具体怎样操作现在还不知道,文件夹中的3个文件分别是:barcodes.tsv,genes.tsv,matrix.mtx,文件的名字不能错,否则读取不到)
pbmc.data <- Read10X(data.dir = "D:/pbmc3k_filtered_gene_bc_matrices/filtered_gene_bc_matrices/hg19/")
## 查看稀疏矩阵的维度,即基因数和细胞数
dim(pbmc.data)
pbmc.data[1:10,1:6]
## 创建Seurat对象与数据过滤,除去一些质量差的细胞(这里读取的是单细胞 count 结果中的矩阵目录;在对象生成的过程中,做了初步的过滤;留下所有在>=3 个细胞中表达的基因 min.cells = 3;留下所有检测到>=200 个基因的细胞 min.genes = 200。)
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
##计算每个细胞的线粒体基因转录本数的百分比(%),使用[[ ]] 操作符存放到metadata中,mit-开头的为线粒体基因
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
##展示基因及线粒体百分比(这里将其进行标记并统计其分布频率,"nFeature_RNA"为基因数,"nCount_RNA"为细胞数,"percent.mt"为线粒体占比)
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
CombinePlots(plots = list(plot1, plot2))
## 过滤细胞:根据上面小提琴图中基因数"nFeature_RNA"和线粒体数"percent.mt",分别设置过滤参数,这里基因数 200-2500,线粒体百分比为小于 5%,保留gene数大于200小于2500的细胞;目的是去掉空GEMs和1个GEMs包含2个以上细胞的数据;而保留线粒体基因的转录本数低于5%的细胞,为了过滤掉死细胞等低质量的细胞数据。
pbmc <- subset(pbmc, subset = nFeature_RNA >200 &nFeature_RNA <2500 &percent.mt <5)
## 表达量数据标准化,LogNormalize的算法:A = log( 1 + ( UMIA ÷ UMITotal ) × 10000
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
#pbmc <- NormalizeData(pbmc) 或者用默认的
## 鉴定表达高变基因(2000个),用于下游分析,如PCA;
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)
## 提取表达量变化最高的10个基因;
top10 <- head(VariableFeatures(pbmc), 10)
top10
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10)
CombinePlots(plots = list(plot1, plot2))
plot1<-VariableFeaturePlot(object=pbmc)
plot2<-LabelPoints(plot=plot1,points=top10,repel=TRUE)
CombinePlots(plots=list(plot1,plot2))
## PCA分析:
# PCA分析数据准备,使用ScaleData()进行数据归一化;默认只是标准化高变基因(2000个),速度更快,不影响PCA和分群,但影响热图的绘制。
#pbmc <- ScaleData(pbmc,vars.to.regress ="percent.mt")
## 而对所有基因进行标准化的方法如下:
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
## 线性降维(PCA),默认用高变基因集,但也可通过features参数自己指定;
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
## 展示 pca 结果(最简单的方法)
DimPlot(object=pbmc,reduction="pca")
## 检查PCA分群结果, 这里只展示前5个PC,每个PC只显示5个基因;
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
##PC_ 1
##Positive: RPS27, MALAT1, RPS6, RPS12, RPL13
##Negative: CSTA, FCN1, CST3, LYZ, LGALS2
##PC_ 2
##Positive: NKG7, GZMA, CST7, KLRD1, CCL5
##Negative: RPL34, RPL32, RPL13, RPL39, LTB
##PC_ 3
##Positive: MS4A1, CD79A, BANK1, IGHD, CD79B
##Negative: IL7R, RPL34, S100A12, VCAN, AIF1
##PC_ 4
##Positive: RPS18, RPL39, RPS27, MALAT1, RPS8
##Negative: PPBP, PF4, GNG11, SDPR, TUBB1
##PC_ 5
##Positive: PLD4, FCER1A, LILRA4, SERPINF1, LRRC26
##Negative: MS4A1, CD79A, LINC00926, IGHD, FCER2
## 展示主成分基因分值
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
## 绘制pca散点图
DimPlot(pbmc, reduction = "pca")
## 画第1个或15个主成分的热图;
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
## 确定数据集的分群个数
# 鉴定数据集的可用维度,方法1:Jackstraw置换检验算法;重复取样(原数据的1%),重跑PCA,鉴定p-value较小的PC;计算‘null distribution’(即零假设成立时)时的基因scores。虚线以上的为可用维度,也可以调整 dims 参数,画出所有 pca 查看。
#pbmc <- JackStraw(pbmc, num.replicate = 100)
#pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
#JackStrawPlot(pbmc, dims = 1:15)
# 方法2:肘部图(碎石图),基于每个主成分对方差解释率的排名。
ElbowPlot(pbmc)
## 细胞聚类:分群个数这里选择10,建议尝试选择多个主成分个数做下游分析,对整体影响不大;在选择此参数时,建议选择偏高的数字(为了获取更多的稀有分群,“宁滥勿缺”);有些亚群很罕见,如果没有先验知识,很难将这种大小的数据集与背景噪声区分开来。
## 非线性降维(UMAP/tSNE)基于PCA空间中的欧氏距离计算nearest neighbor graph,优化任意两个细胞间的距离权重(输入上一步得到的PC维数) 。
pbmc <- FindNeighbors(pbmc, dims = 1:10)
## 接着优化模型,resolution参数决定下游聚类分析得到的分群数,对于3K左右的细胞,设为0.4-1.2 能得到较好的结果(官方说明);如果数据量增大,该参数也应该适当增大。
pbmc <- FindClusters(pbmc, resolution = 0.5)
## 使用Idents()函数可查看不同细胞的分群;
head(Idents(pbmc), 5)
## 结果:AAACCTGAGGTGCTAG AAACCTGCAGGTCCAC AAACCTGCATGGAATA AAACCTGCATGGTAGG AAACCTGCATTGGCGC
1 3 0 10 2
Levels: 0 1 2 3 4 5 6 7 8 9 10 11
## Seurat提供了几种非线性降维的方法进行数据可视化(在低维空间把相似的细胞聚在一起),比如UMAP和t-SNE,运行UMAP需要先安装'umap-learn'包,这里不做介绍,两种方法都可以使用,但不要混用,如果混用,后面的结算结果会将先前的聚类覆盖掉,只能保留一个。
## 这里采用基于TSNE的聚类方法。
pbmc <- RunTSNE(pbmc, dims = 1:10)
## 用DimPlot()函数绘制散点图,reduction = "tsne",指定绘制类型;如果不指定,默认先从搜索 umap,然后 tsne, 再然后 pca;也可以直接使用这3个函数PCAPlot()、TSNEPlot()、UMAPPlot(); cols,pt.size分别调整分组颜色和点的大小;
DimPlot(pbmc,reduction = "tsne",label = TRUE,pt.size = 1.5)
## 这里采用基于图论的聚类方法
pbmc<-RunUMAP(object=pbmc,dims=1:10)
DimPlot(object=pbmc,reduction="umap")
## 细胞周期归类
pbmc<- CellCycleScoring(object = pbmc, g2m.features = cc.genes$g2m.genes, s.features = cc.genes$s.genes)
head(x = [email protected])
DimPlot(pbmc,reduction = "tsne",label = TRUE,group.by="Phase",pt.size = 1.5)
## 存储结果
saveRDS(pbmc, file = "D:/pbmc_tutorial.rds")
save(pbmc,file="D:/res0.5.Robj")
## 寻找cluster 1的marker
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
## 结果: p_val avg_logFC pct.1 pct.2 p_val_adj
MT-CO1 0.000000e+00 -0.6977083 0.985 0.996 0.000000e+00
RPS27 2.182766e-282 0.3076454 1.000 0.999 3.480202e-278
MT-CO3 2.146399e-274 -0.4866429 0.995 0.997 3.422218e-270
DUSP1 2.080878e-247 -1.7621662 0.376 0.745 3.317752e-243
RPL34 8.647733e-244 0.3367755 1.000 0.997 1.378795e-239
##寻找每一cluster的marker
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
# A tibble: 24 x 7
# Groups: cluster [12]
p_val avg_logFC pct.1 pct.2 p_val_adj cluster gene
<dbl> <dbl><dbl><dbl> <dbl><fct> <chr>
1 2.29e-123 0.636 0.344 0.097 3.65e-119 0 CD8B
2 7.62e-113 0.487 0.632 0.305 1.22e-108 0 LEF1
3 2.04e- 74 0.483 0.562 0.328 3.25e- 70 1 LEF1
4 1.39e- 61 0.462 0.598 0.39 2.22e- 57 1 ITM2A
5 0. 2.69 0.972 0.483 0. 2 GNLY
6 0. 2.40 0.964 0.164 0. 2 GZMB
7 1.31e-121 0.768 0.913 0.671 2.09e-117 3 JUNB
8 2.06e- 94 0.946 0.426 0.155 3.28e- 90 3 RGS1
9 2.05e-255 1.57 0.586 0.09 3.27e-251 4 GZMK
10 2.94e-140 1.57 0.69 0.253 4.68e-136 4 KLRB1
# ... with 14 more rows
## 存储marker
write.table(pbmc.markers,file="D:/allmarker.txt")
## 各种绘图
## 绘制Marker 基因的tsne图
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"),cols = c("gray", "red"))
## 绘制Marker 基因的小提琴图
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
## 绘制分cluster的热图
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
剩下的便是寻找基因 marker 并对细胞类型进行注释(见下回分解)