Доступ к данным о `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 файл из теста, который довольно легко выглядит так:

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

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

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

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

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

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

0

Решение

Вы можете получить 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"
2

Другие решения

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

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

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

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

Имеет смысл?

2

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

Я обнаружил, что пакет во время тестирования 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

2
По вопросам рекламы [email protected]