Вот один из возможных подходов:
#include <Rcpp.h>
Rcpp::LogicalVector logical_index(Rcpp::IntegerVector idx, R_xlen_t n) {
bool invert = false;
Rcpp::LogicalVector result(n, false);
for (R_xlen_t i = 0; i < idx.size(); i++) {
if (!invert && idx[i] < 0) invert = true;
result[std::abs(idx[i])] = true;
}
if (!invert) return result;
return !result;
}
// [[Rcpp::export]]
Rcpp::NumericVector
Subset(Rcpp::NumericVector x, Rcpp::IntegerVector idx) {
return x[logical_index(idx, x.size())];
}
x <- seq(2, 10, 2)
x[c(2, 4)]
#[1] 4 8
Subset(x, c(1, 3))
#[1] 4 8
x[-c(2, 4)]
#[1] 2 6 10
Subset(x, -c(1, 3))
#[1] 2 6 10
Обратите внимание, что индексы для функции Rcpp являются 0 на основе, так как они обрабатываются в C++.
Я абстрагировать логику Подменит в свою собственную функцию, logical_index
, который преобразовывает IntegerVector
к LogicalVector
для того, чтобы иметь возможность «принять решение», следует ли удалить или сохранить указанные элементы (например, путем инвертирования результата). Я полагаю, что это можно было бы сделать и с подмножеством на основе целых чисел, но это не должно иметь значения в любом случае.
Как векторное подмножество в R, вектор все отрицательные индексы означают падение соответствующих элементов; тогда как вектор всех положительных индексов указывает на сохранение элементов. Я не проверял смешанные случаи, которые, вероятно, должны были бы исключить, как это сделает R.
Что касается моего последнего комментария, вероятно, было бы более разумно полагаться на родные перегрузках Rcpp для обыкновенных Подменят, и имеет специальную функцию для инверсного подмножества (R в x[-c(...)]
конструкта), а не смешивая функциональность, как описано выше. Существуют ранее существовавшие выражения сахара для создания такой функции, например.
#include <Rcpp.h>
template <int RTYPE>
inline Rcpp::Vector<RTYPE>
anti_subset(const Rcpp::Vector<RTYPE>& x, Rcpp::IntegerVector idx) {
Rcpp::IntegerVector xi = Rcpp::seq(0, x.size() - 1);
return x[Rcpp::setdiff(xi, idx)];
}
// [[Rcpp::export]]
Rcpp::NumericVector
AntiSubset(Rcpp::NumericVector x, Rcpp::IntegerVector idx) {
return anti_subset(x, idx);
}
/*** R
x <- seq(2, 10, 2)
x[-c(2, 4)]
#[1] 2 6 10
AntiSubset(x, c(1, 3))
#[1] 2 6 10
*/
Это должно помочь: http://gallery.rcpp.org/articles/armadillo-subsetting/ –
Вы говорите 'Rcpp/RcppArmadillo', но Rcpp векторы и Armadillo векторы имеют различные интерфейсы. Просьба уточнить это. – nrussell
@DirkEddelbuettel: Я действительно прочитал эту страницу, прежде чем задавать этот вопрос. Возможно, я что-то пропустил, но до сих пор не могу понять, как удалить элементы вместо получения элементов, определенных 'uvec' или' umat'. Не могли бы вы рассказать? – aenima