2017-02-21 3 views
0

Gowerの類似性を計算しようとしています。 Rcppパッケージを使用して、大きなデータでデイジー関数がエラーをスローするのと同じように、類似の値を計算する独自の関数を作成しています。Rcpp関数からNumericVectorsのリストを返します

関数である:

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
List gowerSim(CharacterMatrix inp) { 

    int n_row = inp.nrow(), n_col = inp.ncol(); 
    int sumRow = 0, colLen; 
    List out(n_row); 

    //double sim[n_row]; 
    NumericVector sim(n_row); 

    for (int i = 0; i < n_row; i++) { 

    for (int j = 0; j < n_row; j++) { 

     sumRow = 0; 
     colLen = n_col; 

     for (int k = 0; k < n_col; k++) { 
     if (inp(i,k) != "NA" && inp(j,k) != "NA") { 

      if (inp(i,k) != inp(j,k)) { 
      sumRow = sumRow + 1; 
      } 
     } else { 
      colLen = colLen - 1; 
     } 
     } 
     if (colLen > 0) { 
     sim[j] = (double) sumRow/colLen; 
     //printf("%f",sim[j]); 
     } else { 
     sim[j] = NA_INTEGER; 
     } 
    } 

    out[i] = sim; 

    if (i < 3) { 
     print(out); 
    } 
    } 

    return out; 
} 

/*** R 
clust<-gowerSim(inp) 
*/ 

返されたリストは、他のすべての要素、すなわちにコピーし、最後のベクトルを有する、clustは長さ250を有する場合、clust[[1]]clust[[250]]が同じすべての値を有すると仮定する。しかし、(上位3要素の)各ベクトルout[1]out[2]out[3]の印刷は異なります。

誰でも問題を教えてください。

答えて

1

この問題の解決策は、このように、最初のforコマンドの後ベクトルsimを定義することです:

List gowerSim(CharacterMatrix inp) { 

    int n_row = inp.nrow(), n_col = inp.ncol(); 
    int sumRow=0,colLen; 
    List out(n_row); 

    for(int i=0;i<n_row;i++){ 

    NumericVector sim(n_row); 

    for(int j=0;j<n_row;j++){ 
     sumRow=0; 
     colLen=n_col; 
     for(int k=0; k<n_col;k++){ 
     if(inp(i,k)!="NA" && inp(j,k)!="NA"){ 
      if(inp(i,k)!=inp(j,k)){ 
      sumRow=sumRow+1; 
      } 
     }else{ 
      colLen=colLen-1; 
     } 
     } 
     if(colLen>0){ 
     sim[j] = (double) sumRow/colLen; 
     //printf("%f",sim[j]); 
     }else{ 
     sim[j] = NA_INTEGER; 
     } 
    } 
    out[i] = sim; 
    if(i<3){ 
     print(out); 
    } 
    } 

    return out; 
} 

少し例:

mat <- matrix(as.character(c(rep(1,5),sample(3,15,repl=TRUE),rep(5,5))),5) 
clust <- gowerSim(mat) 
clust 

enter image description here

またはすることができます最初のfor-loopでそれをリセットしてリセットします。

なぜこのアプローチは正しく動作するのですか:あなたは本当にわかりませんが、C++のリスト構造を参照していると思います。あなたの問題を解決するため

私の最初のアプローチは、次のものだった。その代わりに、リストを埋める、我々はマトリックスを充填しており、これは正常に動作し、ここを参照してください:

NumericMatrix gowerSim(CharacterMatrix inp) { 

    int n_row = inp.nrow(), n_col = inp.ncol(); 
    int sumRow=0,colLen; 
    NumericMatrix out(n_row, n_col); 
    NumericVector sim(n_row); 

    for(int i=0;i<n_row;i++); 

    for(int j=0;j<n_row;j++){ 
     sumRow=0; 
     colLen=n_col; 
     for(int k=0; k<n_col;k++){ 
     if(inp(i,k)!="NA" && inp(j,k)!="NA"){ 
      if(inp(i,k)!=inp(j,k)){ 
      sumRow=sumRow+1; 
      } 
     }else{ 
      colLen=colLen-1; 
     } 
     } 
     if(colLen>0){ 
     sim[j] = (double) sumRow/colLen; 
     //printf("%f",sim[j]); 
     }else{ 
     sim[j] = NA_INTEGER; 
     } 
    } 
    out(_,i) = sim; 
    if(i<3){ 
     print(out); 
    } 
    } 

    return out; 
} 
+0

これは多くのことをworked..thanks。あなたは、なぜこれがうまくいったのか、もっと論理的に軽く投げてください。 simはベクトルとして宣言され、イテレータ "i"と "j"のすべての組み合わせに対して類似性を保存してからoutに割り当てます。それでなぜ失敗したのですか? – TUSHAr

関連する問題