从 Rcpp Catch 测试访问 `inst/extdata` 上的数据
Acessing data on `inst/extdata` from Rcpp Catch tests
我正在尝试通过 Rcpp Catch2 测试访问 inst/extdata
文件中的数据文件。文件树如下所示:
├── 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
)
并根据需要使用它。我知道此时使用已安装包的全局路径,但是我找不到将此值传递给我的 C++ 测试的方法。我目前使用的是硬编码路径,但这显然只适用于我的机器。
这是我目前使用的:
const std::string DATAFILE = "/my/package/inst/extdata/data-sample";
因为这是一个读取文件的函数,我真的不能以任何方式嵌入它,但我仍然想知道:如何将 R 数据传递给 Rcpp/Catch 测试?
提前致谢!
不要使用硬编码路径。试着弄清楚你是否需要
包构建时间然后就是../inst/extdata/data-sample/foo.csv
,或者
一次安装在这种情况下它是标准的system.file("extdata/foo.csv", package="yourpackage")
一般来说,这对于 R 包来说有点问题——但即使你这样做 R CMD check
它实际上 首先安装包 所以你在第二个案例.
有道理吗?
您可以通过从 C++ 调用 R 函数来获取 system.file()
路径,即使它不是导出的 C++ 函数(这就是我在对 post 和Dirk Eddelbuettel 的回答)。考虑 print_extdata.cpp
中的以下 C++ 代码:
#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"
我将此添加为另一个答案,因为我只是从 Dirk 和 duckmayr 的答案中得到的。
我发现 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
我正在尝试通过 Rcpp Catch2 测试访问 inst/extdata
文件中的数据文件。文件树如下所示:
├── 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
)
并根据需要使用它。我知道此时使用已安装包的全局路径,但是我找不到将此值传递给我的 C++ 测试的方法。我目前使用的是硬编码路径,但这显然只适用于我的机器。
这是我目前使用的:
const std::string DATAFILE = "/my/package/inst/extdata/data-sample";
因为这是一个读取文件的函数,我真的不能以任何方式嵌入它,但我仍然想知道:如何将 R 数据传递给 Rcpp/Catch 测试?
提前致谢!
不要使用硬编码路径。试着弄清楚你是否需要
包构建时间然后就是
../inst/extdata/data-sample/foo.csv
,或者一次安装在这种情况下它是标准的
system.file("extdata/foo.csv", package="yourpackage")
一般来说,这对于 R 包来说有点问题——但即使你这样做 R CMD check
它实际上 首先安装包 所以你在第二个案例.
有道理吗?
您可以通过从 C++ 调用 R 函数来获取 system.file()
路径,即使它不是导出的 C++ 函数(这就是我在对 post 和Dirk Eddelbuettel 的回答)。考虑 print_extdata.cpp
中的以下 C++ 代码:
#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"
我将此添加为另一个答案,因为我只是从 Dirk 和 duckmayr 的答案中得到的。
我发现 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