3

データフレームの各行と他のすべての行の間の最小ユークリッド距離を見つける (そしてどの行が最も近いかを記録する) 短い「for」ループを作成しました。理論的には、これにより、非常に大きな行列の距離測定を計算しようとすることに関連するエラーが回避されます。ただし、メモリに保存される量はそれほど多くありませんが、大きな行列の場合は非常に遅くなります (私の使用例である ~150K 行はまだ実行中です)。

apply などを使用して、関数をベクトル化するという点で、誰かがアドバイスしたり、正しい方向に向けたりできるかどうか疑問に思っています。簡単な質問に見えるかもしれませんが、ベクトル化された方法で考えるのにまだ苦労しています。

事前に感謝します(そしてあなたの忍耐のために)。

require(proxy)

df<-data.frame(matrix(runif(10*10),nrow=10,ncol=10), row.names=paste("site",seq(1:10)))

min.dist<-function(df) {  
 #df for results
 all.min.dist<-data.frame()
 #set up for loop 
 for(k in 1:nrow(df)) {
     #calcuate dissimilarity between each row and all other rows
     df.dist<-dist(df[k,],df[-k,])
     # find minimum distance
     min.dist<-min(df.dist)
     # get rowname for minimum distance (id of nearest point)
     closest.row<-row.names(df)[-k][which.min(df.dist)]
     #combine outputs
     all.min.dist<-rbind(all.min.dist,data.frame(orig_row=row.names(df)[k],
     dist=min.dist, closest_row=closest.row))
    }
 #return results
 return(all.min.dist)
                        } 
 #example
 min.dist(df)
4

2 に答える 2

3

これは良いスタートになるはずです。高速な行列演算を使用し、成長するオブジェクト構造を回避します。両方ともコメントで提案されています。

min.dist <- function(df) {

  which.closest <- function(k, df) {
    d <- colSums((df[, -k] - df[, k]) ^ 2)
    m <- which.min(d)
    data.frame(orig_row    = row.names(df)[k],
               dist        = sqrt(d[m]),
               closest_row = row.names(df)[-k][m])
  }

  do.call(rbind, lapply(1:nrow(df), which.closest, t(as.matrix(df))))
}

それでも遅すぎる場合は、提案された改善として、単一のポイントではなく、一度にkポイントの距離を計算できます。kのサイズは、速度とメモリ使用量の間で妥協する必要があります。

編集:https://stackoverflow.com/a/16670220/1201032もお読みください

于 2013-05-10T02:53:30.263 に答える
0

通常、組み込み関数は自分でコーディングするよりも高速です (Fortran または C/C++ でコーディングされ、最適化されているため)。

関数 dist {stats} があなたの質問に答えているようです:

説明 この関数は、指定された距離メジャーを使用して計算された距離行列を計算して返し、データ行列の行間の距離を計算します。

于 2013-05-10T03:08:40.513 に答える