-2

R言語を使用して、各行の行列の値から指定されたベクトルまでのユークリッド距離の2乗を見つけています。ベクトルは2つの点を比較するための点であり、この関数を作成します

euclDist <- function(p1, p2){
   sum((p1 - p2)^2)
}

ここで、指定された点までのユークリッド距離が最小である行列内の行を見つける関数を作成したいと考えています

  minDist<- function(points, p){
    dist = c()
    for(i in seq(1:length(points[,1])))
      dist[i] = euclDist2(points[i,], p)
    which.min(dist)
 }

例えば

points = matrix(c(1:24), ncol=4)
p = c(1,2,1,2)
print(minDist(points, p))

最初の行は点 p までの距離が最小であるため、結果は1です。

これは正常に動作しますが、適用バリエーションの 1 つを使用して for ループを取り除きたいのですが、行ごとに行列で機能し、複数の引数をサポートするものを見つけることができません。

編集:最初のコードに括弧と括弧に問題があったため、この質問は改訂されました:-(

4

2 に答える 2

2

そのはず

minDist <- function(points, p) which.min(apply(points, 1, euclDist, p2 = p))

しかし、一般にapply、単純なforループよりもはるかに高速ではありません。はるかに効率的なコードを書く方法が 2 つあります。

最初のものは、R のベクトル化とリサイクルを使用します。

minDist <- function(points, p) which.min(colSums((t(points) - p)^2))

2 つ目はrdist、パッケージの関数を使用してfields、2 組のポイント間のユークリッド距離を計算できます。

minDist <- function(points, p) {
    require(fields)
    which.min(rdist(points, t(matrix(p))))
}

どちらのソリューションも、を使用するよりもはるかに高速ですapply

于 2012-12-06T00:56:13.983 に答える
0

問題は for ループの代わりに apply を使用する方法であるため、次のようにします。

ベクトルを取得するには:

   dist <- sapply(points, euclDist, p)   # no need for the dist <- c()

リストを取得するには:

   dist <- lapply(points, euclDist, p)   # no need for the dist <- c()

ただし、コードには他にもいくつかの問題があることに注意してください。最も注目すべきは、ユークリッド距離を計算しているかどうかわかりません

于 2012-12-05T19:04:58.833 に答える