我有一个包含4列的5131行的R data.frame
对象,其示例如下:
1 X 12830000 12910000 C
2 X 12960000 13510000 C
3 X 13525000 13675000 C
4 X 13670000 13715000 C
5 X 13670000 13770000 E2
6 X 13670000 14050000 E3
7 X 13765000 14050000 E1
8 X 13910000 14050000 E1
9 X 13940000 14050000 C
10 X 15360000 15590000 E3
这是一个基因组.bed
文件,第2列是一段DNA的起始位置坐标,第3列是结束位置,第4列是关于它的一些元信息。因此,根据它们的坐标,这可以被想象成彼此重叠的弦。
我想写一个R脚本,它执行以下操作:
如果彼此之间的行之间存在重叠,则选择重叠中长度最长的行。在已排序示例数据中,按顺序向下移动,第4行和第5行,第5行和第6行,第6行和第7行,第7行和第8行以及第8行和第9行之间的重叠次数超过40000次其中第6行是最长的。在4和5中,第5行是最长的,所以我保留5.在第5行和第6行之间,6是最长的,所以我保持6.我一直这样做 直到我找到一个重叠小于4000的行,并选择其中最长的一行。
所以我的新数据框应该是这样的:
1 X 12830000 12910000 C
2 X 12960000 13510000 C
3 X 13525000 13675000 C
6 X 13670000 14050000 E3 <- (keeping the longest one)
10 X 15360000 15590000 E3
到目前为止,我尝试执行以下操作:
output_4 <- fr_t[NULL,]
for(i in 1:nrow(fr_t)-1){
if(isTRUE(fr_t[i+1,]$V3-fr_t[i,]$V2<40000||fr_t[i,]$V3-fr_t[i+1,]$V2 < 40000)) {
if(isTRUE((fr_t[i+1,]$V3-fr_t[i+1,]$V2)>(fr_t[i+2,]$V3-fr_t[i+2,]$V2))){
next
}
next
}
output_4 <- rbind(output_4, fr_t[i+2,])
} #fr_t is my original dataframe
我无法弄清楚如何迭代我的i
直到重叠的行,以保持最长的行。
另外,如何将第4列中的元信息保存为重叠矩阵?例如,一个新的数据框如下:
E3 C E2 E1 E1 C
第一列是最大行的第4列,所有其他列是其中重叠列的第4列?这将需要具有不同列数的对象。谢谢你的耐心等待。
答案 0 :(得分:2)
首先,我完全同意@ zacdav的评论。看看R / Bioconductor包GenomicRanges
;它是为这类操作而开发的。有一些很棒的教程,例如here和here。
关于您的问题,以下内容将再现您的预期输出:
# Your sample data as a data.frame
df <- read.table(text =
"1 X 12830000 12910000 C
2 X 12960000 13510000 C
3 X 13525000 13675000 C
4 X 13670000 13715000 C
5 X 13670000 13770000 E2
6 X 13670000 14050000 E3
7 X 13765000 14050000 E1
8 X 13910000 14050000 E1
9 X 13940000 14050000 C
10 X 15360000 15590000 E3", header = F, row.names = 1)
# Convert data.frame to GRanges
library(GenomicRanges);
gr <- with(df, GRanges(
seqnames = df[, 1],
IRanges(start = df[, 2], end = df[, 3]),
id = df[, 4]))
# Find overlapping regions within gr
hits <- findOverlaps(gr, gr, minoverlap = 40000);
# Remove self-overlapping hits
hits <- hits[queryHits(hits) != subjectHits(hits)];
# Determine features that are shorter than the overlapping feature
mcols(hits)$queryWidth = width(gr[queryHits(hits)]);
mcols(hits)$subjectWidth = width(gr[subjectHits(hits)]);
mcols(hits)$hit <- ifelse(
mcols(hits)$queryWidth < mcols(hits)$subjectWidth,
queryHits(hits),
subjectHits(hits));
# Remove those shorter overlapping features
gr.final <- gr[-unique(mcols(hits)$hit)];
gr.final;
#GRanges object with 5 ranges and 1 metadata column:
# seqnames ranges strand | id
# <Rle> <IRanges> <Rle> | <factor>
# [1] X [12830000, 12910000] * | C
# [2] X [12960000, 13510000] * | C
# [3] X [13525000, 13675000] * | C
# [4] X [13670000, 14050000] * | E3
# [5] X [15360000, 15590000] * | E3
如果您想将gr.final
转换回data.frame
,可以使用as.data.frame(gr.final)
。