Я пытаюсь получить доступ к файлу данных на 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?
Заранее спасибо!
Вы можете получить 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"
Не используйте жестко закодированный путь. Попробуйте попытаться выяснить, если вам нужно в
время сборки пакета и тогда это будет ../inst/extdata/data-sample/foo.csv
, или же
один раз установлены в этом случае это стандарт system.file("extdata/foo.csv", package="yourpackage")
Это небольшая проблема для пакетов R в целом — но даже когда вы делаете R CMD check
это на самом деле сначала устанавливает пакет так что вы во втором случае.
Имеет смысл?
Я добавляю это как другой ответ, поскольку я получил это только от ответов Дирка и Дакмейра.
Я обнаружил, что пакет во время тестирования 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