Найти 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
Разбираем это немного больше шагов:
Порядок А, по абсолютному расстоянию от интересующей позиции,
t
,- Код является:
A[order(abs(seq_len(length(A)) - t))]
- Код является:
Подмножество к первому
R*2
элементы (так что это будет получать элементы по обе стороны отt
вR
,- Код является:
[seq_len(R*2)]
- Код является:
- Получить первый
min(N, # of non-NA, len of non-NA)
элементы- Код является:
min(sum(is.na(orderedA)), N, length(na.omit(orderedA)))
- Код является:
- Капля
NA
- Код является:
na.omit()
- Код является:
- Возьмите первые элементы, определенные на шаге 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))