WedX - журнал о программировании и компьютерных науках

Возврат подмножества данного SEXP без знания фактического внутреннего типа данных

Я пишу пакет R для предоставления вспомогательных функций отладки для gdb для печати значений переменных Rs SEXP и Rcpps типы данных.

C / C ++ - это строго типизированный язык, но я хочу избежать запроса внутреннего типа данных SEXP и использовать кучу if для жестко заданной диспетчеризации.

Как я могу реализовать универсальную функцию подмножества, используя диапазон индекса через сигнатуру функции, подобную этой:

SEXP dbg_subset(SEXP x, R_xlen_t index_from, R_xlen_t index_to);

Одним из возможных решений было бы написать указанную выше функцию для каждой возможной подписи, например. для INTSXP, LGLSXP, _10 _... но я ленив ;-)

Примечание. Я не могу использовать шаблоны C ++, потому что компоновщик будет создавать экземпляры шаблонов только для типов данных, используемых в моем коде C ++ (которые не такие, как в «отлаживаемой библиотеке»), а gdb не является компилятором, который мог бы создавать отсутствующие экземпляры шаблона "на лету", когда выражения C ++ вводятся для запроса переменных.

Изменить: см. этот ответ (но он основан на шаблонах, которых я хочу избежать):

21.11.2019


Ответы:


1

Вы можете использовать шаблон C ++ вместе с макросом RCPP_RETURN_VECTOR. Этот макрос гарантирует, что шаблон создан для всех (?) Типов данных R:

#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]

template <int RTYPE>
Rcpp::Vector<RTYPE> debug_subset_impl(Rcpp::Vector<RTYPE> x,
                                      R_xlen_t index_from,
                                      R_xlen_t index_to){
    // range [index_from, index_to)
    Rcpp::Vector<RTYPE> subset(index_to - index_from);
    std::copy(x.cbegin() + index_from, x.cbegin() + index_to, subset.begin());
    // special case for factors == INTSXP with "class" and "levels" attribute
    if (x.hasAttribute("levels")){
        subset.attr("class") = x.attr("class");
        subset.attr("levels") = x.attr("levels");
    }
    return subset;
}


// [[Rcpp::export]]
SEXP dbg_subset(SEXP x, R_xlen_t index_from, R_xlen_t index_to){
    // 1-based -> 0-based
    RCPP_RETURN_VECTOR(debug_subset_impl, x, index_from - 1, index_to - 1);
}

/*** R
set.seed(42)
dbg_subset(1:100, 3, 6)
dbg_subset(runif(100), 3, 6)
dbg_subset(letters, 3, 6)
dbg_subset(as.factor(letters), 3, 6)
*/

Вывод:

> Rcpp::sourceCpp('58965423.cpp')

> set.seed(42)

> dbg_subset(1:100, 3, 6)
[1] 3 4 5

> dbg_subset(runif(100), 3, 6)
[1] 0.2861395 0.8304476 0.6417455

> dbg_subset(letters, 3, 6)
[1] "c" "d" "e"

> dbg_subset(as.factor(letters), 3, 6)
[1] c d e
Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z
21.11.2019
  • THX много за то, что нашел время предоставить нетривиальную реализацию, это то, что я искал! 24.11.2019
  • Просто просмотрите комментарии (для других читателей, которые хотят использовать код) о том, как я расширил код: std::copy копирует от начала до конца минус 1, поэтому последний элемент отсутствовал (легко исправить); проверка диапазона индексов необходима для предотвращения ошибок сегментации; атрибуты должны всегда сохраняться (по крайней мере, R делает); data.frame подмножество возвращает неправильный результат (подмножества столбцов, а не строк, поскольку RCPP_RETURN_VECTOR знает только списки, но не data.frame) 24.11.2019
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]