在计算R中保持某些条目恒定的矢量化方法

l7wslrjt  于 2023-05-26  发布在  其他
关注(0)|答案(1)|浏览(137)

我试图计算图上第一个点和所有其他点之间的欧氏距离。我不能用dplyr做这个。但是代码似乎在我使用for loop时运行。我想知道解决这个问题的矢量化方法是什么。
样本代码:

set.seed(5)

#create data 
df <- data.frame("x" = runif(100, 0, 1)) %>%
  mutate(y = log(x)) %>%
  arrange(x)

#Function takes two tuples consisting of coordinate data and returns the euclidian distance between the points
euc_dist = function(a, b) {
  return(sqrt(sum(a - b) ^ 2))
}

我试着在数据框上运行这个。首先,我认为一种方法行不通:

df %>%
  mutate(dist = euc_dist(c(x[1], y[1]), 
                         c(x, y)))

生成一个具有常量值的变量dist,而不是为每一行生成一个值。所以我尝试了一些我认为可行的方法,但那有点麻烦。

df %>%
  mutate(dist = euc_dist(c(df$x[1], df$y[1]), 
                         c(x, y)))

这产生与上述相同的结果。
我想要的是这样的等价物:

output <- c()           
for (i in 1:nrow(df)) {
  out <- euc_dist(c(df$x[1], df$y[1]),
                  c(df$x[i], df$y[i]))
  output <- append(output, out)
}

这很好。
有没有一种方法可以通过矢量化的方法来实现这一点,最好是在dplyr中?

ldxq2e6h

ldxq2e6h1#

euc_dist函数中,我会替换sum(),因为它是对所有值求和,而不是逐行求和。

euc_dist <- function(x1, y1, x2, y2) {
  return(sqrt( ((x2 - x1) ^ 2) + ((y2 - y1) ^ 2) ) )
}

因为你想保持(x1, y1)不变,所以在调用这个函数时需要显式。
完整的解决方案是

library(dplyr)

set.seed(5)

#create data 
df <- data.frame("x" = runif(100, 0, 1)) %>%
  mutate(y = log(x)) %>%
  arrange(x)

euc_dist <- function(x1, y1, x2, y2) {
  return(sqrt( ((x2 - x1) ^ 2) + ((y2 - y1) ^ 2) ) )
}

df %>%
  mutate(dist = euc_dist(x1 = df$x[1], y1 = df$x[1], x2 = x, y2 = y))

#              x           y      dist
# 1   0.01448234 -4.23482504 4.2493074
# 2   0.02272462 -3.78430650 3.7987978
# 3   0.03114826 -3.46899692 3.4835191
# 4   0.03901895 -3.24370787 3.2582826
# 5   0.05006142 -2.99450467 3.0091974
# ... etc

注意,现在dist列对x列没有意义。因此,您可能需要考虑x是否实际上有意义。如果没有,可以将第一个(x, y)对作为常量放入函数中。

相关问题