R:向量a中的元素与向量b中的元素之间的最小距离

3
ab 是两个实数向量。
它们的长度不一定相同。
定义 a 的第 i 个元素和 b 的第 j 个元素之间的距离为 abs(a[i] - b[j])
不使用显式循环,您将如何计算 a 的任何元素和 b 的任何元素之间的最小距离?
这是我的做法:min(sapply(X=1:length(b), FUN=function(x) abs(a - b[x])))
然而,我感觉还有更好的方法...

@Joshua:一个反例:a = c(9 5 6),b = c(6, 9)。谢谢。 - user7064
@JoshuaUlrich,OP想要任意点对之间的最小距离,而不是每个向量的最小值对之间的距离。 - Paul Hiemstra
3个回答

4
我会使用dist函数创建一个距离矩阵,然后在其中找到最小距离。这可能比在R中使用显式循环(包括sapply)要快得多。
a = runif(23)
b = runif(10)
d_matrix = as.matrix(dist(cbind(a,b)))
d_matrix[d_matrix == 0] <- NA
sqrt(min(d_matrix, na.rm = TRUE))

请注意,cbind会循环使用较小的向量。所以这个函数可能不是最优的,但对于大小差异不大的向量而言,仍比显式循环要快得多。
如果要找到具有此距离的哪一对元素(尽管循环使用会带来一些挑战):
which(d_matrix == min(d_matrix, na.rm = TRUE), arr.ind = TRUE)

谢谢!我认为当a和b的长度不同时它不能工作。有没有可能进行调整? - user7064
ab的长度不相等时,cbind将简单地重复较小的向量。因此,min(d_matrix)仍将返回最小值。我修改了我的示例。 - Paul Hiemstra
好的,关于长度问题。最后一件事:当 a = c(7, 9, 11) 且 b = c(5, 13) 时,您的代码返回 4。我有遗漏什么吗? - user7064
“dist”使用平方距离,取最小值的平方根即可得到正确答案。 - Paul Hiemstra

3

以下是一个尝试:

a <- c(9,5,6); b <- c(6,9)
# a
#[1] 9 5 6
# b
#[1] 6 9

combos <- sapply(b,function(x) abs(x-a))
# or an alternative
combos <- abs(outer(a,b,FUN="-"))

你可以使用以下方法获取最小距离:

min(combos)

如果您想获取最小值的各自索引,则可以执行以下操作:
which(combos==min(combos),arr.ind=TRUE)

# each matrix row has the 2 indexes for the minimums
# first column is 'a' index, second is 'b' index
#      row col
# [1,]   3   1
# [2,]   1   2

我喜欢“外部解决方案” :-) - user7064
那么你应该接受那个作为你的答案,绿色的勾号表示哪个答案对你最有帮助。 - Paul Hiemstra

2

在这里应该使用一行代码:min(abs(outer(a, b, "-")))


非常好 :-) 我接受了 @thelatemail 的答案,他建议先处理外部。无论如何,+1并非常感谢! - user7064

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接