0

100行x2500列のテーブルの各行間のペアワイズ差の数を計算しようとしています。

私はこれを行う小さなRScriptを持っていますが、実行時間は(明らかに)非常に長いです!Cでループを書き込もうとしていますが、エラーが発生し続けます(compileCode)。

次のループをCに「変換」する方法について何か考えがありますか?

pw.dist <- function (vec1, vec2) {

return( length(which(vec1!=vec2)) )

}

N.row <- dim(table)[1]
pw.dist.table <- array( dim = c(dim(table)[1], dim(table)[1]))

for (i in 1:N.row) {
    for (j in 1:N.row) {
        pw.dist.table[i,j] <- pw.dist(table[i,-c(1)], table[j,-c(1)])
    }
}

私は次のようなことを試みています:

sig <- signature(N.row="integer", table="integer", pw.dist.table="integer")
code <- "
  for( int i = 0; i < (*N.row) - 1; i++ ) {
    for( int j = i + 1; j < *N.row; j++ ) {
      int pw.dist.table = table[j] - table[i];
    }
  }
"
f <- cfunction( sig, code, convention=".C" )

プログラミングに関しては、私は完全な初心者です。

前もって感謝します。JMFA

4

2 に答える 2

5

コードの最適化を試みる前に、どこで時間が費やされているかを確認することをお勧めします。

Rprof()
... # Your loops
Rprof(NULL)
summaryRprof()

あなたの場合、ループは遅くありませんが、距離関数は遅いです。

$by.total
                    total.time total.pct self.time self.pct
"pw.dist"                37.98     98.85      0.54     1.41
"which"                  37.44     97.45     34.02    88.55
"!="                      3.12      8.12      3.12     8.12

次のように書き換えることができます (1 秒かかります)。

# Sample data
n <- 100
k <- 2500
d <- matrix(sample(1:10, n*k, replace=TRUE), nr=n, nc=k)
# Function to compute the number of differences
f <- function(i,j) sum(d[i,]!=d[j,])
# You could use a loop, instead of outer,
# it should not make a big difference.
d2 <- outer( 1:n, 1:n, Vectorize(f) )
于 2012-05-30T12:15:43.323 に答える
1

上記の Vincent は正しい考えを持っています。さらに、行列が R でどのように機能するかを利用して、さらに高速な結果を得ることができます。

n <- 100
k <- 2500
d <- matrix(sample(1:10, n*k, replace=TRUE), nr=n, nc=k)
system.time(d2 <- outer( 1:n, 1:n, Vectorize(f) ))
#precompute transpose of matrix - you can just replace 
#dt with t(d) if you want to avoid this
system.time(dt <- t(d))
system.time(sapply(1:n, function(i) colSums( dt[,i] != dt)))

出力:

#> system.time(d2 <- outer( 1:n, 1:n, Vectorize(f) ))
#   user  system elapsed 
#    0.4     0.0     0.4 
#> system.time(dt <- t(d))
#   user  system elapsed 
#      0       0       0 
#> system.time(sapply(1:n, function(i) colSums( dt[,i] != dt)))
#   user  system elapsed 
#   0.08    0.00    0.08 
于 2012-05-30T13:03:13.703 に答える