我有两个有几千点的向量,但在这里概括:
A <- c(10, 20, 30, 40, 50)
b <- c(13, 17, 20)
我怎样才能得到A
最接近的指标b
?预期的结果是c(1, 2, 2)
。
我知道findInterval
只能找到第一个出现,而不是最近的出现,而且我知道它which.min(abs(b[2] - A))
正在变暖,但我无法弄清楚如何对其进行矢量化以使用 和 的长A
向量b
。
我有两个有几千点的向量,但在这里概括:
A <- c(10, 20, 30, 40, 50)
b <- c(13, 17, 20)
我怎样才能得到A
最接近的指标b
?预期的结果是c(1, 2, 2)
。
我知道findInterval
只能找到第一个出现,而不是最近的出现,而且我知道它which.min(abs(b[2] - A))
正在变暖,但我无法弄清楚如何对其进行矢量化以使用 和 的长A
向量b
。
你可以把你的代码放在一个 sapply 中。我认为这与 for 循环具有相同的速度,因此在技术上并没有矢量化:
sapply(b,function(x)which.min(abs(x - A)))
FindInterval 让您非常接近。您只需要在它返回的偏移量和下一个偏移量之间进行选择:
#returns the nearest occurence of x in vec
nearest.vec <- function(x, vec)
{
smallCandidate <- findInterval(x, vec, all.inside=TRUE)
largeCandidate <- smallCandidate + 1
#nudge is TRUE if large candidate is nearer, FALSE otherwise
nudge <- 2 * x > vec[smallCandidate] + vec[largeCandidate]
return(smallCandidate + nudge)
}
nearest.vec(b,A)
返回 (1,2,2),并且在性能上应该与 FindInterval 相当。
这是一个使用 R 经常被忽视的outer
功能的解决方案。不确定它是否会表现得更好,但它确实避免了sapply
.
A <- c(10, 20, 30, 40, 50)
b <- c(13, 17, 20)
dist <- abs(outer(A, b, '-'))
result <- apply(dist, 2, which.min)
# [1] 1 2 2