如何创建一个函数来输入两个向量以生成矩阵

How do you create a function to input two vectors to produce a matrix

假设我有 5 对向量形式的坐标 (x1,y1)(region1) , (x2,y2)(region2) 等等直到 (x5,y5)(region5)。 现在我想找出每个区域之间的距离。例如,我拿 距离,D = √[(i−)^2+(−)^2] 在区域 i 和 j 之间,输出将是一个 5 x 5 矩阵,其中矩阵 (Dij) 中的每个条目是两个区域之间的距离.

例如,我有区域 1,其坐标为 (4,3) 和区域 2 (1,2)。那么这两个区域之间的距离应该是 D = √10 并且这应该在 Dij 的条目中,其中 i = 1 和 j = 2,因此如上矩阵所示为 D12。 我尝试了如下所示的代码:

x=c(1,2,4,1,1)
y=c(4,3,1,2,2)
Distance = function(x,y){
D = sqrt(abs((x[i]-x[j])^2+(y[i]-y[j])^2))
A = matrix(0,nrow=5,ncol=5,T)
i = nrow(A)
j = ncol(A)
for (i in 1:5){
for (j in 1:5){
A[i][j] = D
}
}
return(A) 
} 

输出:

Warning messages:
 1: In A[i] <- `*vtmp*` :
 number of items to replace is not a multiple of replacement length

这些警告消息中有 20 条。叹。我知道我的代码远非正确。请帮忙

代码存在以下问题。

  • 定义 D 的行使用了 i 和 j,即使它们在那时还没有定义
  • 定义 D 的行使用 abs(...) 但 (...) 中的部分从不为负,因此使用 abs 毫无意义
  • 如果 x[i], y[i] 是第 i 个点,那么 x 和 y 的长度必须相同,所以我们应该检查一下。
  • 定义 A 的行硬编码 5,因此该函数仅在 x 和 y 的长度为 5 时才有效。
  • 矩阵的第四个参数是 T。切勿使用 T 表示 TRUE。总是写出来,因为 T 是一个可能的变量,但 TRUE 永远不能是变量名。
  • 在定义矩阵时指定 byrow = TRUE 是没有意义的,因为每个元素都被赋予相同的值,所以顺序无关紧要。事实上,我们根本不需要填写 A,因为稍后的循环会这样做。
  • i和j定义为nrow(A)和ncol(A);然而,紧接着它们被重新定义,因此原始定义被丢弃并且从未使用过。这些行没有效果。
  • 这两个循环将上限硬编码为 5,因此,同样,该函数仅在 x 和 y 的长度均为 5 时才有效。
  • A[i][j] 应该是 A[i, j]
  • D 在循环中使用,但在循环外定义,因此 A[i,j] 的每个元素都将被赋予相同的值
  • 代码未缩进,难以阅读
  • 在代码中加入更多空格会更易于阅读
  • 虽然写return(A)并没有错,只写A就足以return了
  • 问题涉及输出但没有输出,因为代码从未运行函数

代码--

Distance = function(x, y) {
  stopifnot(length(x) == length(y))
  n = length(x)
  A = matrix(nrow = n, ncol = n)
  for (i in 1:n) {
    for (j in 1:n) {
      A[i, j] = sqrt( (x[i] - x[j])^2 + (y[i] - y[j])^2 )
    }
  }
  A
} 

# test
x = c(1, 2, 4, 1, 1)
y = c(4, 3, 1, 2, 2)
Distance(x, y)
##        [,1]   [,2]   [,3]   [,4]   [,5]
## [1,] 0.0000 1.4142 4.2426 2.0000 2.0000
## [2,] 1.4142 0.0000 2.8284 1.4142 1.4142
## [3,] 4.2426 2.8284 0.0000 3.1623 3.1623
## [4,] 2.0000 1.4142 3.1623 0.0000 0.0000
## [5,] 2.0000 1.4142 3.1623 0.0000 0.0000

请注意,使用外部可以更紧凑地完成此操作。

d <- function(i, j) sqrt((x[i] - x[j])^2 + (y[i] - y[j])^2)
n <- length(x)
outer(1:n, 1:n, Vectorize(d))
##        [,1]   [,2]   [,3]   [,4]   [,5]
## [1,] 0.0000 1.4142 4.2426 2.0000 2.0000
## [2,] 1.4142 0.0000 2.8284 1.4142 1.4142
## [3,] 4.2426 2.8284 0.0000 3.1623 3.1623
## [4,] 2.0000 1.4142 3.1623 0.0000 0.0000
## [5,] 2.0000 1.4142 3.1623 0.0000 0.0000