我在R中有2个数据帧,例如df和dfrefseq。
df<-data.frame( chr = c("chr1","chr1","chr1","chr4")
, start = c(843294,4329248,4329423,4932234)
, stop = c(845294,4329248,4529423,4935234)
, genenames= c("HTA","OdX","FEA","MGA")
)
dfrefseq<-data.frame( chr = c("chr1","chr1","chr1","chr2")
, start = c(843294,4329248,4329423,4932234)
, stop = c(845294,4329248,4529423,4935234)
, genenames= c("tra","FGE","FFs","FAA")
)
我想检查dfrefseq中每个基因的dfrefseq最接近所选的df基因。 我首先在两个数据帧中选择了“chr1”。 然后我计算了readschr1中第一个基因开始 - 开始 - 停止 - 停止 - 开始和停止 - 停止位点之间的距离。 这些计算的总和说明了距离的一切。我的问题是,如何加快分析速度?因为现在我只针对数据帧测试了1个基因,但我需要测试2000个基因。
readschr1 <- subset(df,df[,1]=="chr1")
refseqchr1 <- subset(dfrefseq,dfrefseq[,1]=="chr1")
names<-list()
read_start_start<-list()
read_start_stop<-list()
read_stop_start<-list()
read_stop_stop<-list()
for (i in 1:nrow(refseqchr1)) {
startstart<-abs(readschr1[1,2] - refseqchr1[i,2])
startstop<-abs(readschr1[1,2] - refseqchr1[i,3])
stopstart<-abs(readschr1[1,3] - refseqchr1[i,2])
stopstop<-abs(readschr1[1,3] - refseqchr1[i,3])
read_start_start[[i]]<- matrix(startstart)
read_start_stop[[i]]<- matrix(startstop)
read_stop_start[[i]]<- matrix(stopstart)
read_stop_stop[[i]]<- matrix(stopstop)
names[[i]]<-matrix(refseqchr1[i,4])
}
table<-cbind(names, read_start_start, read_start_stop, read_stop_start, read_stop_stop)
sumtotalcolumns<-as.numeric(table[,2]) + as.numeric(table[,3])+ as.numeric(table[,4]) + as.numeric(table[,5])
test<-cbind(table, sumtotalcolumns)
test1<-test[order(as.vector(test$sumtotalcolumns)), ]
谢谢!
答案 0 :(得分:4)
Bioconductor包GenomicRanges
旨在处理此类数据
source('http://bioconductor.org/biocLite.R')
biocLite('GenomicRanges') # one-time installation
然后
library(GenomicRanges)
gr <- with(df,
GRanges(factor(chr, levels=paste("chr", 1:4, sep="")),
IRanges(start, stop), genenames=genenames))
grrefseq <- with(dfrefseq,
GRanges(factor(chr, levels=paste("chr", 1:4, sep="")),
IRanges(start, stop), genenames=genenames))
和
> nearest(gr, grrefseq)
[1] 1 2 3 NA
答案 1 :(得分:1)
您可以merge
将两个单独的data.frames组合在一起形成一个表,然后使用矢量化操作。 merge
的关键是指定data.frames之间的公共列,并告诉它在有不匹配的情况下该怎么做。如果在其他data.frame中没有匹配,则指定all = TRUE
将返回所有行并填充NA,在这种情况下为ch2和ch4。一旦data.frames被合并,那么这是一个简单的练习,可以相互减去不同的列,然后将感兴趣的四列相加。我使用transform
来减少进行减法所需的输入。
zz <- merge(df, dfrefseq, by = "chr", all = TRUE)
zz <- transform(zz,
read_start_start = abs(start.x - start.y)
, read_start_stop = abs(start.x - stop.y)
, read_stop_start = abs(stop.x - start.y)
, read_stop_stop = abs(stop.x - stop.y)
)
zz <- transform(zz,
sum_total_columns = read_start_start + read_start_stop + read_stop_start + read_stop_stop
)
这是一种获得最小距离的行的方法。我假设你想通过chr和genenames这样做。我使用的是plyr
软件包,但我确信如果您更喜欢其中一种,我们会有基本的解决方案。也许其他人会使用基础解决方案。
require(plyr)
ddply(zz, c("chr", "genenames.x"), function(x) x[which.min(x$sum_total_columns) ,])