dbscan聚类算法的R实现

来源:互联网 发布:js获取div文本内容 编辑:程序博客网 时间:2024/05/29 01:52

首先,先讲下需要解决的问题:

问题:挑选出了一条染色体上的一些gene位点,用dbscan算法检查下这些基因在位置上有没有聚集。

输入文件:(ID,start,end) 

gene0001        1       1323
gene0002        1483    2619
gene0003        2580    4889
gene0009        14089   14664

PS:基因已按照起始位置排序


DBSCAN核心思想:如果一个点,在距它Eps的范围内有不少于MinPts个点,则该点就是核心点。核心和它Eps范围内的邻居形成一个簇。在一个簇内如果出现多个点都是核心点,则以这些核心点为中心的簇要合并。


R代码实现:

<pre name="code" class="plain">args<-commandArgs(TRUE)dat<-read.table(args[1],sep="\t",header=F,row.names=1)outfile<-args[2]dis<-function(start1,end1,start2,end2){ ###计算两点之间距离        start_p=max(start1,start2);        end_p=min(end1,end2);        if (start_p<end_p){return(0);}        else{         dis=start_p-end_p;         return(dis);        }}center_cluster<-function(dis,center,n,e){  #####寻找核心点和范围内的邻居,e(Eps),n(MinPts)        cluster<-center;        while(TRUE){                if (min(cluster)!=1 && dis[center,min(cluster)-1]<=e){                        left=dis[center,min(cluster)-1];                }                else{                        left=10000;                }               if (max(cluster)!=nrow(dis) && dis[max(cluster)+1,center]<=e){                        right= dis[max(cluster)+1,center];                }                else{                        right=10000;                }                if (left >right){cluster<-c(cluster,max(cluster)+1);}                else if (left <right){cluster<-c(min(cluster)-1,cluster);}                else if (left==right &&left!=10000){cluster<-c(min(cluster)-1,cluster);}                else{break;}        }        if (length(cluster)>=n){                return (cluster);        }        else{                return (NULL);        }}region_cluster<-function(dis,n,e){  ###将有overlap的核心簇连接成region        region<-rep(0,nrow(dis));        r<-1;        for (i in 1:nrow(dis)){                cluster=center_cluster(dis,i,n,e);                if (length(cluster)){                        if (max(region[cluster]!=0)){                                region[cluster]=max(region[cluster]);                        }                        else{                                region[cluster]=r;                                r<-r+1;                        }                }        }        return(region);}gene_dis<-matrix(0,nrow(dat),nrow(dat)); for (i in 1:nrow(dat)){        for (j in 1:i){                gene_dis[i,j]=dis(dat[i,1],dat[i,2],dat[j,1],dat[j,2]);        }}result<-as.data.frame(region_cluster(gene_dis,6,3000));rownames(result)<-rownames(dat);colnames(result)<-"cluster";if ( max(result$cluster)>0 ){        out<- matrix(0,max(result$cluster),2)        for (i in 1:max(result$cluster)){                out[i,]=c( dat[min(which(result$cluster==i)),1],dat[max(which(result$cluster==i)),2])        }        out<- as.data.frame(out)        colnames(out)<-c("start","end")        rownames(out)<-paste("region",rownames(out),sep="")        write.table(out,outfile,quote=F, col.names = NA,sep="\t")}else{        write.table(t(c("","start","end")),outfile,quote=F,sep="\t",col.names=F,row.names=F) }


输出格式:

        start   end
region1  11111  12000

region2  12001 120002


dbscan已有R包,写的代码没有卵用,但还是祭奠下~~~ 大笑



0 0
原创粉丝点击