找到n个最接近的非NA值,将t置于向量中

时间:2017-06-19 19:48:00

标签: r vector closest

对于那些在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最近的非NA值到t,使它们落在以R为中心的半径t内。即,搜索半径RR+1值组成。例如A,搜索半径序列为(3,NA,3,NA,4,NA,1),其中t=NA是搜索半径序列中的中间值。

预期答案可以是A:

的两个结果之一
answerA1 <- c(3,4,1)

OR

answerA2 <- c(3,4,3)

B的预期答案:

answerB <- c(1,3)

我如何以最节省时间和空间的方式完成这项任务?欢迎使用一个衬垫,线圈等。如果我必须选择偏好,那就是速度!

提前致谢!

注意:

对于这种情况,我理解第三个最接近的非NA值可能涉及选择第三个值的偏好落在t的右侧或左侧(如两个所示)可能的答案)。我没有偏好这个值是否落在t的左侧或右侧,但是,如果有办法将其留给随机机会,(第三个值是否落在右侧或左侧)这将是理想的(但同样,这不是一个要求)。

3 个答案:

答案 0 :(得分:2)

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

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元素的子集(因此,这将在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)]

答案 1 :(得分:1)

这样的东西?

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

当然,这会优先考虑左侧。

答案 2 :(得分:0)

如果它对其他人有帮助,@ 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))

相关问题