Найти n ближайших значений, отличных от NA, для положения t в векторе

Вероятно, это простой вопрос для тех, кто имеет опыт работы с R, но с этим я (новичок) борюсь...

У меня есть два примера векторов, которые являются общими для проблемы, которую я пытаюсь решить, A а также B:

A <- c(1,3,NA,3,NA,4,NA,1,7,NA,2,NA,9,9,10)
B <- c(1,3,NA,NA,NA,NA,NA,NA,NA,NA,2,NA,9)

#and three scalars
R <- 4
t <- 5
N <- 3

Есть четвертый скаляр, n, где 0<=n<=N, В общем, N <= R,

Я хочу найти n ближайшийNA значения для t так что они попадают в радиус R сосредоточено на t, Т.е. радиус поиска, R состоит из R+1 ценности. Например, последовательность радиусов поиска (3,NA,3,NA,4,NA,1), где t=NA, среднее значение в последовательности радиуса поиска.

Ожидаемый ответ может быть одним из двух результатов для A:

answerA1 <- c(3,4,1)

ИЛИ ЖЕ

answerA2 <- c(3,4,3)

Ожидаемый ответ для B:

answerB <- c(1,3)

Как бы я справился с этой задачей наиболее экономичным по времени и пространству способом? Одни лайнеры, петли и т. Д. Приветствуются. Если мне нужно выбрать предпочтение, это для скорости!

Заранее спасибо!

Замечания:

Для этого случая я понимаю, что третий ближайшийNA значение может включать в себя выбор предпочтения для третьего значения, чтобы упасть справа или слева от t (как показано двумя возможными ответами выше). У меня нет предпочтения, падает ли это значение влево или вправо от t но, если есть способ оставить его на случайную случайность, (независимо от того, падает ли третье значение вправо или влево), это было бы идеально (но, опять же, это не является обязательным требованием).

3 ответа

Решение

Относительно короткое решение:

orderedA <- A[order(abs(seq_len(length(A)) - t))][seq_len(R*2)]
n_obj <- min(sum(is.na(orderedA)), N, length(na.omit(orderedA)))
res <- na.omit(orderedA)[seq_len(n_obj)]

res
#[1] 3 4 3

Разбираем это немного больше шагов:

  1. Порядок А, по абсолютному расстоянию от интересующей позиции, t,

    • Код является: A[order(abs(seq_len(length(A)) - t))]
  2. Подмножество к первому R*2 элементы (так что это будет получать элементы по обе стороны от t в R,

    • Код является: [seq_len(R*2)]
  3. Получить первый min(N, # of non-NA, len of non-NA) элементы
    • Код является: min(sum(is.na(orderedA)), N, length(na.omit(orderedA)))
  4. Капля NA
    • Код является: na.omit()
  5. Возьмите первые элементы, определенные на шаге 3 (в зависимости от того, что меньше)
    • Код является: [seq_len(n_obj)]

Что-то вроде этого?

thingfinder <- function(A,R,t,n) {
  left <- A[t:(t-R-1)]
  right <- A[t:(t+R+1)]
  leftrightmat <- cbind(left,right)
  raw_ans <- as.vector(t(leftrightmat))
  ans <- raw_ans[!is.na(raw_ans)]
  return(ans[1:n])
}

thingfinder(A=c(1,3,NA,3,NA,4,NA,1,7,NA,2,NA,9,9,10), R=3, t=5, n=3)
##  [1] 3 4 3

Это, конечно, отдает приоритет левой стороне.

В случае, если это будет полезно другим, @Mike H. также предоставил мне решение вернуть индекс positions связанные с желаемыми элементами вектора res:

A <- setNames(A, seq_len(length(A)))

orderedA <- A[order(abs(seq_len(length(A)) - t))][seq_len(R*2)]

n_obj <- min(sum(is.na(orderedA)), N, length(na.omit(orderedA)))

res <- na.omit(orderedA)[seq_len(n_obj)]

positions <- as.numeric(names(res))

Другие вопросы по тегам