2013-04-16 5 views
4

У меня есть кадр данных R с вектором чисел, представляющих положения вдоль хромосомы и вектора имен генов. У меня также есть вектор стартовых позиций интересных элементов на этой хромосоме. Я хотел бы извлечь имена и позиции из трех ближайших генов как над, так и под каждым элементом, и мне интересно, как это сделать.Эффективно найти смежные значения в векторе

Например:

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 
+0

Когда вы говорите 3 ближе, вы имеете в виду ген, который содержит элемент, то либо 3 выше и 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 в зависимости от ваших предпочтений.

+0

+1 Я шел по этим строкам с помощью 'findInterval', но я рассматривал возможность переключения idx-2/idx + 3 в зависимости от того, где начальная позиция в гене была –

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)) 
} 
+0

. Этот ответ кажется мне лучше, чем 1) он находит «самые близкие гены» ('findInterval (99, c (1,10,100)) дает 2, в то время как нам хотелось бы 3, поскольку 99 ближе всего к 100). И 2) он решает проблемы ребер массива. Незначительная точка; не было бы более эффективным/удобочитаемым, чтобы предварительно вычислить 'abs (гены [, 1] -x)' вместо того, чтобы иметь выражение дважды? –

+0

Вы правы. Вероятно, было бы более эффективно предварительно вычислять абсолютные различия. Я просто хотел оставить свое решение в трех строках ... –

Смежные вопросы