2015-11-03 2 views
7

Начальный вопрос, когда я изучаю классы/структуры данных Rcpp: существует ли функция-член для стирания строки/столбца для объекта класса Rcpp::NumericMatrix? (Или другие типы type **Matrix - Я предполагаю, что это класс шаблонов)?Rcpp NumericMatrix - как удалить строку/столбец?

library(Rcpp) 
cppFunction(' 
    NumericMatrix sub1 {NumericMatrix x, int& rowID, int& colID) { 
    // let's assume separate functions for rowID or colID 
    // but for the example case here 
    x.row(rowID).erase(); // ??? does this type of member function exist? 
    x.col(colID).erase(); // ??? 
    return x; 
}') 

Если этого типа функции-члена не существует, как насчет этого?

cppFunction('NumericMatrix row_erase (NumericMatrix& x, int& rowID) { 
    // a similar function would exist for removing a column. 
    NumericMatrix x2(Dimension(x.nrow()-1, x.ncol()); 
    int iter = 0; // possibly make this a pointer? 
    for (int i = 0; i < x.nrow(); i++) { 
    if (i != rowID) { 
     x2.row(iter) = x.row(i); 
     iter++; 
    } 
    } 
    return x2; 
}') 

Или, возможно, мы хотим, чтобы удалить набор строк/столбцов:

cppFunction('NumericMatrix row_erase (NumericMatrix& x, IntegerVector& rowID) { 
    // a similar function would exist for removing a column. 
    rowID = rowID.sort(); 

    NumericMatrix x2(Dimension(x.nrow()- rowID.size(), x.ncol()); 
    int iter = 0; // possibly make this a pointer? 
    int del = 1; // to count deleted elements 
    for (int i = 0; i < x.nrow(); i++) { 
    if (i != rowID[del - 1]) 
     x2.row(iter) = x.row(i); 
     iter++; 
    } else { 
     del++; 
    } 
    } 
    return x2; 
}') 
+1

Я отвечал на подобный вопрос [здесь] (http://stackoverflow.com/questions/33119163/rcpp-eliminating -a-column-and-a-row-from-a-matrix), который (я думаю) объединяет обе ваши цели в одну функцию. Если это так, вы можете легко адаптировать его к двум отдельным функциям для устранения строк и столбцов, соответственно. – nrussell

+0

@nrussell - спасибо, я посмотрю –

ответ

0

Да, оба они работают (фиксация моих опечаток выше). Я получил ошибку преобразования, пытаясь заменить int iter на Rcpp::NumericMatrix::iterator iter. Любое исправление для этого?

Обратите внимание, что нам не нужен row_erase(NumericMatrix& x, int& ref), так как это специальный случай row_erase(NumericMatrix& x, IntegerVector& ref).

NumericMatrix row_erase (NumericMatrix& x, IntegerVector& rowID) { 
    rowID = rowID.sort(); 

    NumericMatrix x2(Dimension(x.nrow()- rowID.size(), x.ncol())); 
    int iter = 0; 
    int del = 1; // to count deleted elements 
    for (int i = 0; i < x.nrow(); i++) { 
    if (i != rowID[del - 1]) { 
     x2.row(iter) = x.row(i); 
     iter++; 
    } else { 
     del++; 
    } 
    } 
    return x2; 
} 

NumericMatrix col_erase (NumericMatrix& x, IntegerVector& colID) { 
    colID = colID.sort(); 

    NumericMatrix x2(Dimension(x.nrow(), x.ncol()- colID.size())); 
    int iter = 0; 
    int del = 1; 
    for (int i = 0; i < x.ncol(); i++) { 
    if (i != colID[del - 1]) { 
     x2.col(iter) = x.column(i); 
     iter++; 
    } else { 
     del++; 
    } 
    } 
    return x2; 
} 
4

Как насчет использования RcppArmadillo? Я думаю, что назначение кода будет намного понятнее ...

#include <RcppArmadillo.h> 
// [[Rcpp::depends(RcppArmadillo)]] 

using namespace arma; 

// [[Rcpp::export]] 
mat sub1(mat x, uword e) { 
    x.shed_col(e-1); 
    x.shed_row(e-1); 
    return x; 
} 

/*** R 
sub1(matrix(1:9,3), 2) 
*/ 

> sub1(matrix(1:9,3), 2) 
    [,1] [,2] 
[1,] 1 7 
[2,] 3 9 
+1

Спасибо! Есть ли вероятность, что вы можете дать аналогичный ответ Eigen? –

+0

Eigen не предоставляет функцию convience для этого типа операции, насколько я знаю ... Если мне нужно _manipulate_ данные, хранящиеся в матрице, я выбираю Armadillo над Eigen каждый раз. – Thell

+0

Хм --- хорошо знать. У меня все еще есть Eigen/Armadillo в моем списке. У вас есть предпочтения? Поиск, который я сделал, был неубедительным. –

Смежные вопросы