Доступ к данным по `inst / extdata` из тестов Rcpp Catch

Я пытаюсь получить доступ к файлу данных в файле inst/extdata из теста Rcpp Catch2. Дерево файлов выглядит так:

├── inst
│   └── extdata
│       └── data-sample
├── R
│   ├── catch-routine-registration.R
│   └── RcppExports.R
├── src
    ├── mycode.cpp
    ├── RcppExports.cpp
    ├── Package_types.h
    ├── test-example.cpp
    └── test-runner.cpp

Я полагаю, что это было бы похоже на то, что вы получили бы от скелета нового пакета с помощью devtools. Теперь я могу легко получить доступ к этому файлу data-sample из теста test, вот так:

system.file(
    "extdata", "data-sample", package = "Package", mustWork = TRUE
)

И используйте его по мере надобности. Я знаю, что на данный момент здесь используется глобальный путь из установленного пакета, однако я не могу найти способ передать это значение в мои тесты C++. В настоящее время я использую жестко запрограммированный путь, но он, очевидно, работает только на моей машине.

Вот что я сейчас использую:

const std::string DATAFILE = "/my/package/inst/extdata/data-sample";

Поскольку это функция для чтения файлов, я действительно не могу встроить ее каким-либо образом, но я все еще хочу знать: как передать данные R в тесты Rcpp / Catch?

Заранее спасибо!

Вы спрашиваете, как получить возвращаемое значение вызова функции R system.file("extdata", "data-sample", package = "Package", mustWork = TRUE) из C++?

duckmayr 25.10.2018 01:37

@duckmayr Да, это решило бы мою проблему, однако мне нужно передать это на C++, который вызывается R. Поскольку это тестовый файл, я не могу передать ему Function.

Yuri-M-Dias 25.10.2018 01:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
142
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Не используйте жестко запрограммированный путь. Попробуйте разобраться, нужно ли вам в

  • время сборки пакета и тогда это будет ../inst/extdata/data-sample/foo.csv, или

  • один раз установлены и в этом случае это стандартный system.file("extdata/foo.csv", package = "yourpackage")

Это небольшая проблема для пакетов R в целом, но даже когда вы используете R CMD check, на самом деле это сначала устанавливает пакет, так что вы находитесь во втором случае.

Имеет смысл?

Да, мне нужен именно этот второй футляр. Однако как я могу передать это в тесты C++? Я не думаю, что мой вопрос оставил это ясным, но это основная проблема, с которой я столкнулся. Я могу протестировать второй случай в тестах R, как хочу, но не если я хочу провести аналогичный тест в Rcpp, который я не могу (или лучше не хочу) подвергать R. хотите знать, как передать этот путь к файлу system.file после его установки в тесты Catch.

Yuri-M-Dias 25.10.2018 01:39
Ответ принят как подходящий

Вы можете получить путь system.file(), вызвав функцию R из C++, даже если это не экспортированная функция C++ (именно так я интерпретировал ваш запрос, следуя комментариям к сообщению и ответу Дирка Эддельбюттеля). Рассмотрим следующий код C++ в print_extdata.cpp:

#include <Rcpp.h>

Rcpp::StringVector get_extdata(){
    Rcpp::Environment base("package:base");
    Rcpp::Function sys_file = base["system.file"];
    Rcpp::StringVector res = sys_file("extdata", "2012.csv",
                                      Rcpp::_["package"] = "testdat");
    return res;
}


// [[Rcpp::export]]
void print_extdata() {
    Rcpp::StringVector path = get_extdata();
    Rcpp::Rcout << path;
}

Затем позвонил из R:

> Rcpp::sourceCpp("print_extdata.cpp")
> print_extdata()
"/home/duckmayr/R/x86_64-pc-linux-gnu-library/3.5/testdat/extdata/2012.csv"

Принято, потому что это было именно то, что мне было нужно, спасибо! Я обнаружил, что пакет в настоящее время не зарегистрирован на стороне тестирования, поэтому, хотя он работает в обычном сеансе R / при использовании пакета, я не могу понять, почему он не может найти пакет во время тестирования ... Я посмотрю на него подробнее.

Yuri-M-Dias 25.10.2018 04:28

Я добавляю это как еще один ответ, так как я получил его только из ответов Дирка и Дакмайра.

Я обнаружил, что пакет во время тестирования Rcpp еще не был загружен, поэтому ответ duckmayr не сработал из коробки. Однако после некоторой игры я обнаружил, что его код, когда он вызывается только с опцией package, выводит текущий путь к проекту, и поэтому я обнаружил, что в этот момент пакет будет загружен, но с путем из репозитория проекта.

Это действительно немного сбивает с толку, поскольку тесты, использующие R, работают с установочной папкой R, как и ожидалось (например, /home/user/R/x86_64-pc-linux-gnu-library/3.5/). Мне нужно копнуть глубже, чтобы понять, почему это так.

В конце концов, я использовал эту функцию, чтобы получить путь в тестах:

#include <Rcpp.h>
#include <string>

std::string get_datapath_fromR(std::string filename, std::string packageName)
{
    Rcpp::Environment base("package:base");
    Rcpp::Function sys_file = base["system.file"];
    // "inst" field is necessary at this point
    Rcpp::StringVector file_path_sv = sys_file(
        "inst", "extdata", filename,
        Rcpp::_["package"] = packageName,
        Rcpp::_["mustWork"] = true
    );
    std::string file_path = Rcpp::as<std::string>(file_path_sv);
    return file_path;
}

И я могу назвать это на тесте так:

...
std::string datafile = get_datapath_fromR("data-sample", "package");        
...

И в результате получаем вот это: /home/user/path/to/package/folder/packageName/inst/extdata/data-sample

Другие вопросы по теме