在向量中找到 n 个最接近位置 t 的非 NA 值

Find n closest non-NA values to position t in vector

对于那些有 R 经验的人来说,这可能是一个简单的问题,但这是我(新手)正在努力解决的问题...

我有两个向量示例,它们对于我要解决的问题是常见的,AB

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 最接近 t 的非 NA 值,使它们落在以 t 为中心的半径 R 内。即,搜索半径 R 包含 R+1 个值。例如A,搜索半径序列为(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)

我如何才能以最省时 space 的方式完成这项任务?欢迎使用衬垫、环等。如果非要选一个,那是速度!

提前致谢!

注:

对于这种情况,我了解到第三个最接近的非 NA 值可能涉及为第三个值选择落在 t 右侧或左侧的首选项(如所示以上两个可能的答案)。我对这个值是落在 t 的左边还是右边没有偏好,但是,如果有办法让它随机发生,(第三个值是落在右边还是左边)那将是理想的(但是,同样,这不是必需的)。

是这样的吗?

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

这当然会优先考虑左侧。

一个相对简短的解决方案是:

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. 顺序A,通过与感兴趣位置的绝对距离,t

    • 代码为A[order(abs(seq_len(length(A)) - t))]
  2. 子集到第一个 R*2 元素(因此这将得到 Rt 两侧的元素。

    • 代码为: [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)]

如果对其他人有帮助,@Mike H. 还为我提供了 return 与所需向量元素相关联的索引 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))