如何用向量化方法(含dplyr)计算首点与其他点的欧氏距离?
问题与解决方案
问题
需要计算数据框中第一个点与所有其他点的欧氏距离,使用dplyr尝试时生成的dist列为常量(而非每行对应距离),但for循环可正常得到预期结果,寻求基于dplyr的向量化实现方法。
原因分析
原自定义函数euc_dist的实现存在逻辑问题:当传入c(x, y)时,会将整个x和y列拼接成长向量,与第一个点的二元向量c(x[1], y[1])相减后,sum()会将所有差值求和得到单个值,最终导致mutate生成的dist列全为同一个常量。
解决方案
方法1:直接在dplyr中计算(无需自定义函数)
利用dplyr的first()函数获取第一个点的坐标,直接逐行计算欧氏距离:
set.seed(5) df <- data.frame("x" = runif(100, 0, 1)) %>% mutate(y = log(x)) %>% arrange(x) # 向量化计算 df <- df %>% mutate(dist = sqrt((x - first(x))^2 + (y - first(y))^2))
方法2:修改自定义函数为向量化版本
重新定义支持逐行计算的函数,再结合dplyr调用:
# 向量化欧氏距离函数:接收单个点的坐标,以及所有点的x、y列 euc_dist_vec <- function(a_x, a_y, b_x, b_y) { sqrt((a_x - b_x)^2 + (a_y - b_y)^2) } # dplyr调用 df <- df %>% mutate(dist = euc_dist_vec(first(x), first(y), x, y))
验证结果一致性
可以通过与原for循环结果对比验证:
# 原for循环实现 output <- c() for (i in 1:nrow(df)) { out <- sqrt((df$x[1] - df$x[i])^2 + (df$y[1] - df$y[i])^2) output <- append(output, out) } # 验证是否相等 all.equal(df$dist, output) # 输出:TRUE
内容的提问来源于stack exchange,提问作者MorrisseyJ
相关产品推荐
相关产品推荐

