高效地在向量中查找相邻的值

4
我有一个R数据框,其中包含一列数字向量代表沿染色体的位置和一列基因名称的向量。我还有一个有趣元素在该染色体上的起始位置的向量。我想提取每个元素上下3个最接近的基因的名称和位置,我想知道最有效的方法。
例如:
genes <- data.frame("geneStart"=sort(sample(500,10)), "geneName"=sample(LETTERS,10))
genes
   geneStart geneName
1         66        X
2        158        U
3        262        N
4        385        D
5        387        H
6        418        Z
7        464        J
8        469        Y
9        475        L
10       491        I

我希望最后得到一个函数,我们称之为getAdjacent,内容如下:

getAdjacent(280)
[1] "X" "U" "N" "D" "H" "Z"
getAdjacent(479)
[1] "J" "Y" "L" "I" NA NA

当您说“最近的3个”时,您是指包含该元素的基因,然后是3个上方和2个下方,还是相反?您是根据基因长度来决定的吗? - Simon O'Hanlon
2个回答

3
使用findInterval函数:
getAdjacent <- function(x) {
   idx       <- findInterval(x, genes$geneStart)
   range.idx <- (idx-2):(idx+3)
   range.idx <- ifelse(range.idx <= 0, NA, range.idx)
   as.character(genes$geneName)[range.idx]
}

如果x属于genes$geneStart,根据您的偏好可能需要调整行为。


+1 我正在使用 findInterval 进行类似的操作,但我在考虑如果基因的起始位置不同,是否应该根据情况切换 idx-2 / idx+3。 - Simon O'Hanlon

2

我的版本:

getAdjacent <-function(x){
ind <-which(abs(genes[,1]-x)==min(abs(genes[,1]-x))) #which row is closest
out <-genes[max(1,ind-3):min(nrow(genes),ind+2),2]   #indexed for closest match
return(as.character(out))
}

这个答案对我来说更好,因为它可以找到“最接近的基因”(findInterval(99,c(1,10,100))得到2,而我们想要3,因为99最接近100)。并且它解决了数组边缘的问题。小问题是,预先计算abs(genes[,1]-x)而不是两次表达式是否更有效/可读? - Quentin Geissmann
你说得对。预先计算绝对差可能会更有效率。我只是想让我的解决方案保持在三行之内... - Pierre Lapointe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接