Extension R en C, définition des noms de lignes / colonnes de la masortingce

J’écris un paquet R qui manipule des masortingces en C. Actuellement, les masortingces renvoyées à R ont des numéros pour les noms de lignes / colonnes. Je préférerais assigner mes propres noms de lignes / colonnes lors de la modification de l’object en C.

J’ai cherché sur Google pendant environ une heure, mais je n’ai pas encore trouvé de bonne solution. Le nom le plus proche que j’ai trouvé est dimnames, mais je veux nommer chaque colonne, pas seulement les deux dimensions. Les masortingces dépassent les 4×4. Ci-dessous, voici un petit exemple de ce que je veux faire.

Le nombre de lignes est 4 ^ x où X est la longueur du nom de la ligne

Current [,1] [,2] [,3] [,4] [1,] 0.20 0.00 0.00 0.80 [2,] 0.25 0.25 0.25 0.25 [3,] 0.25 0.25 0.25 0.25 [4,] 1.00 0.00 0.00 0.00 [5,] 0.20 0.00 0.00 0.80 [6,] 0.25 0.25 0.25 0.25 [7,] 0.25 0.25 0.25 0.25 [8,] 1.00 0.00 0.00 0.00 [9,] 0.20 0.00 0.00 0.80 [10,] 0.25 0.25 0.25 0.25 [11,] 0.25 0.25 0.25 0.25 [12,] 1.00 0.00 0.00 0.00 [13,] 0.20 0.00 0.00 0.80 [14,] 0.25 0.25 0.25 0.25 [15,] 0.25 0.25 0.25 0.25 [16,] 1.00 0.00 0.00 0.00 Desired [A] [C] [G] [T] [AA] 0.20 0.00 0.00 0.80 [AC] 0.25 0.25 0.25 0.25 [AG] 0.25 0.25 0.25 0.25 [AT] 1.00 0.00 0.00 0.00 [CA] 0.20 0.00 0.00 0.80 [CC] 0.25 0.25 0.25 0.25 [CG] 0.25 0.25 0.25 0.25 [CT] 1.00 0.00 0.00 0.00 [GA] 0.20 0.00 0.00 0.80 [GC] 0.25 0.25 0.25 0.25 [GG] 0.25 0.25 0.25 0.25 [GT] 1.00 0.00 0.00 0.00 [TA] 0.20 0.00 0.00 0.80 [TC] 0.25 0.25 0.25 0.25 [TG] 0.25 0.25 0.25 0.25 [TT] 1.00 0.00 0.00 0.00 

Comme Jim l’a dit, c’est beaucoup plus facile à faire en R. Je passe les noms à la fonction C via l’argument nam .

 #include  SEXP myMat(SEXP nam) { /*PrintValue(nam);*/ SEXP ans, dimnames; PROTECT(ans = allocMasortingx(REALSXP, length(nam), length(nam))); PROTECT(dimnames = allocVector(VECSXP, 2)); SET_VECTOR_ELT(dimnames, 0, nam); SET_VECTOR_ELT(dimnames, 1, nam); setAtsortingb(ans, R_DimNamesSymbol, dimnames); UNPROTECT(2); return(ans); } 

Si vous placez ce code dans un fichier nommé myMat.c , vous pouvez le tester via la ligne ci-dessous. J’utilise Ubuntu, vous devrez donc remplacer myMat.so par myMat.dll si vous utilisez Windows.

 R CMD SHLIB myMat.c Rscript -e 'dyn.load("myMat.so"); .Call("myMat", c("A","C","G","T"))' 

Si vous êtes ouvert au C ++ au lieu du C, alors Rcpp peut vous faciliter la tâche. Nous créons simplement un object de liste avec des noms de lignes et de colonnes, comme nous le ferions dans R, et l’ dimnames atsortingbut dimnames de l’object masortingx:

 R> library(inline) # to comstack, link, load the code here R> src <- ' + Rcpp::NumericMatrix x(2,2); + x.fill(42); // or more interesting values + // C++0x can assign a set of values to a vector, but we use older standard + Rcpp::CharacterVector rows(2); rows[0] = "aa"; rows[1] = "bb"; + Rcpp::CharacterVector cols(2); cols[0] = "AA"; cols[1] = "BB"; + // now create an object "dimnms" as a list with rows and cols + Rcpp::List dimnms = Rcpp::List::create(rows, cols); + // and assign it + x.attr("dimnames") = dimnms; + return(x); + ' R> fun <- cxxfunction(signature(), body=src, plugin="Rcpp") R> fun() AA BB aa 42 42 bb 42 42 R> 

L’affectation réelle des noms de colonne et de ligne est tellement manuelle … car la norme C ++ actuelle ne permet pas l’affectation directe de vecteurs à l’initialisation, mais cela va changer.

Edit: Je viens de me rendre compte que je peux bien sûr utiliser la méthode statique create() sur la ligne et les noms de fichiers aussi, ce qui rend cela un peu plus facile et plus court encore

 R> src <- ' + Rcpp::NumericMatrix x(2,2); + x.fill(42); // or more interesting values + Rcpp::List dimnms = // two vec. with static names + Rcpp::List::create(Rcpp::CharacterVector::create("cc", "dd"), + Rcpp::CharacterVector::create("ee", "ff")); + // and assign it + x.attr("dimnames") = dimnms; + return(x); + ' R> fun <- cxxfunction(signature(), body=src, plugin="Rcpp") R> fun() ee ff cc 42 42 dd 42 42 R> 

Il ne rest donc plus que trois ou quatre déclarations, pas de singe avec PROTECT / UNPROTECT ni de gestion de la mémoire.

La note ci-dessus est instructive. Les dimnames sont une liste avec le même nombre d’éléments que les dimensions de l’dataset, chaque élément correspondant au nombre d’éléments le long de cette dimension, c.-à-d. list(c('a','c','g','t'), c('a','c','g','t')) .

Pour définir cela en C, je recommanderais:

 PROTECT(dimnames = allocVector(VECSXP, 2)); PROTECT(rownames = allocVector(STRSXP, 4)); PROTECT(colnames = allocVector(STRSXP, 4)); setAtsortingb( ? , R_DimNamesSymbol, dimnames); 

Vous devrez ensuite définir les éléments rowname et colname appropriés. En général, cela est beaucoup plus facile à faire en R.

Jim