Доступ к именам измерений из sp_mat в Rcpp Armadillo - PullRequest
0 голосов
/ 30 августа 2018

Я новичок в Rcpp и пытаюсь определить, как получить доступ к именам измерений ввода, чтобы я мог использовать их позже в сценарии. В частности, я пытаюсь извлечь имена столбцов из разреженной матрицы в Armadillo и использовать их для имен строк в отдельном объекте.

Пример для уточнения: Давайте начнем с генерации тривиальной разреженной матрицы.

   input_mat <- Matrix::Matrix(sample(c(0,1), 35, replace =T)
                        ,nrow = 5
                        ,ncol = 7
                        ,dimnames = list(LETTERS[1:5], letters[1:7]))

Далее, давайте использовать это, чтобы сделать что-то в Rcpp. Мы выведем числовую матрицу, заполненную некоторыми случайными числами. nrow выхода = ncol входа.

cppFunction('NumericMatrix map_columns(arma::sp_mat x, int k) {
              int n = x.n_cols;
              NumericMatrix new_mat = NumericMatrix(n, k);
              for(int i = 0; i < n; i++) {
                for(int j = 0; j < k; j++) {
                    new_mat(i,j) = rand() % 100 + 1; 
                }
              }
              rownames(new_mat) = CharacterVector::create("a", "b", "c", "d", "e", "f", "g");
              return(new_mat);
              }', depends = "RcppArmadillo"
              )

map_columns(input_mat, 4)

Вместо того, чтобы вручную указывать имена строк new_mat, я хочу взять имена столбцов x и назначить имена на лету. Я попытался получить доступ к именам слотов разреженной матрицы и попытался назначить их так же, как в R, но не повезло.

Я предполагаю, что совершаю простую ошибку. Может кто-нибудь помочь мне решить это? Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 30 августа 2018

Я не знаю возможности доступа к слотам S4 после преобразования в объект Armadillo, однако вы можете передать разреженную матрицу как объект S4 в функцию и явно обработать преобразование:

input_mat <- Matrix::rsparsematrix(5, 7, 0.2)
input_mat@Dimnames <- list(LETTERS[1:5], letters[1:7])


Rcpp::cppFunction('NumericMatrix map_columns(Rcpp::S4 y, int k) {
              arma::sp_mat x = Rcpp::as<arma::sp_mat>(y);
              int n = x.n_cols;
              NumericMatrix new_mat = NumericMatrix(n, k);
              for(int i = 0; i < n; i++) {
                for(int j = 0; j < k; j++) {
                    new_mat(i,j) = rand() % 100 + 1; 
                }
              }
              Rcpp::List dimnames = y.slot("Dimnames");
              Rcpp::CharacterVector colnames = dimnames[1];
              rownames(new_mat) = colnames;
              return(new_mat);
              }', depends = "RcppArmadillo"
)

map_columns(input_mat, 4)

Обратите внимание, что я создаю разреженную матрицу вместо плотной матрицы, найденной в вашем примере кода.

Примечание: не используйте rand(). Используйте R's RNG, <random> из C ++ 11 или ...

...