我有两个data.frames m
(23列135.973行)和两个重要的列
head(m[,2])
# [1] "chr1" "chr1" "chr1" "chr1" "chr1" "chr1"
head(m[,7])
# [1] 3661216 3661217 3661223 3661224 3661564 3661567
和search
(4列1.019.423行),包含三个重要的列
head(search[,1])
# [1] "chr1" "chr1" "chr1" "chr1" "chr1" "chr1"
head(search[,3])
# [1] 3000009 3003160 3003187 3007262 3028947 3050944
head(search[,4])
# [1] 3000031 3003182 3003209 3007287 3028970 3050995
对于m中的每一行,如果m
[XX,7]位置位于search
[,3]和search
的任何位置之间,我想获取信息[,4 ]。因此search
[,3]可以被视为“开始”而search
[,4]被视为“结束”。此外,search
[,1]和m
[,2]必须完全相同。
示例:
第215行 m
“chr1”10.984.038
点击search
第2898行
“chr1”10.984.024 10.984.046
一般来说,我不感兴趣的是哪一行或search
可以找到多少行。我只想知道m
中任何一行的信息是search
是或否的匹配行。
我结束了这个功能:
f_4<-function(x,y,z){
for (out in 1:length(x[,1])) {
z[out]<-length(which((y[,1]==x[out,2]) &(x[out,7]>=y[,3]) &(x[out,7]<=y[,4])))
}
return(z)
}
found4<-vector(length=length(m[,1]), mode="numeric")
found4<-f_4(m,search,found4)
运行此代码需要3个小时。 我已经尝试了一些加速方法,但是我没有设法让这些运行正常或更快。
我甚至尝试了一些lappy
/ apply
方法 - 虽然有效但速度不快 - 。但是,在尝试使用parLapply
/ parRapply
加速时,他们失败了。
任何人都有一个更快的方法,可能会给出一些建议吗?
编辑2015/09/18
使用foreach
%dopar%
找到另一种加速方式。
f5<-function(x,y,z){
foreach(out=1:length(x[,1]), .combine="c") %dopar% {
takt<-1000
z=length(which((y[,1]==x[out,2]) &(x[out,7]>=y[,3]) &(x[out,7]<=y[,4]) ))
}
return(z)
}
found5<-vector(length=length(m[,1]), mode="numeric")
found5<-f5(m,search,found5)
仅需45分钟。但是我总是只有0。我需要阅读更多foreach
%dopar%
教程。
答案 0 :(得分:1)
您可以尝试与后续逻辑子集合并。首先,让我们创建一些模拟数据:
set.seed(123) # used for reproducibility
m <-as.data.frame(matrix(sample(50,7000, replace=T), ncol=7, nrow=1000))
search <- as.data.frame(matrix(sample(50,1200, replace=T), ncol=4, nrow=300))
由于我们要比较两组的不同行,我们可以使用m[,2]
应该等于search[,1]
的标准。为方便起见,我们可以命名这些列&#34; ID&#34;在两组中:
m <- cbind(m,seq_along(1:nrow(m)))
search <- cbind(search,seq_along(1:nrow(search)))
colnames(m) <- c("a","ID","c","d","e","f","val","rownum.m")
colnames(search) <- c("ID","nothing","start","end", "rownum.s")
我们在名为&#39; rownum.m&#39;的m
中添加了一列。以及与search
类似的列,最后将有助于识别初始数据集中的结果条目。
现在我们可以合并数据集,这样ID就是相同的:
m2 <- merge(m,search)
在最后一步中,我们可以执行合并数据集的逻辑子集,并将输出分配给新数据框m3
:
m3 <- m2[(m2[,"val"] >= m2[,"start"]) & (m2[,"val"] <= m2[,"end"]),]
#> head(m3)
# ID a c d e f val rownum.m nothing start end rownum.s
#5 1 14 36 36 31 30 25 846 10 20 36 291
#13 1 34 49 24 8 44 21 526 10 20 36 291
#17 1 19 32 29 44 24 35 522 6 33 48 265
#20 1 19 32 29 44 24 35 522 32 31 50 51
#21 1 19 32 29 44 24 35 522 10 20 36 291
#29 1 6 50 10 13 43 22 15 10 20 36 291
如果我们只对TRUE/FALSE
语句感兴趣,m
的特定行是否与标准匹配,我们可以定义向量match_s
:
match_s <- m$rownum.m %in% m3$rownum.m
可以存储为原始数据集m
中的附加列:
m <- cbind(m,match_s)
最后,我们可以删除辅助列&#39; rownum.m&#39;来自m
的不再需要的数据集m <- m[,-8]
。
结果是:
> head(m)
# a ID c d e f val match_s
#1 15 14 8 11 16 13 23 FALSE
#2 40 30 8 48 42 50 20 FALSE
#3 21 9 8 19 30 36 19 TRUE
#4 45 43 26 32 41 33 27 FALSE
#5 48 43 25 10 15 13 4 FALSE
#6 3 24 31 33 8 5 36 FALSE
答案 1 :(得分:0)
如果您试图在一组基因组区域内找到SNP(例如),请不要使用R.使用BEDOPS。
将您的SNP或单基地位置转换为三列BED文件。在R中,制作一个包含m[,2]
,m[,7]
和m[,7] + 1
的三列数据表,它代表SNP的染色体,起始和终止位置。使用write.table()
将此数据表写入制表符分隔的文本文件。
对您的基因组区域执行相同操作:将search[,1]
,search[,3]
和search[,4]
写入表示该区域的染色体,起始和停止位置的三列数据表。使用write.table()
将其写入制表符分隔的文本文件。
使用sort-bed
to sort both BED files。此步骤可能是可选的,但它不需要很长时间,并且可以保证文件已准备好与BEDOPS工具一起使用。
最后,use bedmap
on the two BED files to map SNPs to genomic regions。映射将SNP与区域相关联。 bedmap
工具可以报告哪些SNP映射到某个区域,或报告SNP的数量,或者报告许多其他操作中的一个或多个。 bedmap
的{{3}}详细介绍了操作列表,但documentation可以让您快速入门。
如果您的数据采用BED格式,或者可以快速强制转换为BED格式,请不要使用R进行基因组操作,因为它速度慢且占用大量内存。 BEDOPS工具包引入了使用排序来快速进行基因组操作,并且内存开销很低。