所以我从 C++ 调用一些 R 代码,并且为此直接调用 R.dll(我了解 Rcpp,我的 table 上有这本书,但我不能用它来这个具体的事情)。我有一个设置变量的 R 脚本,我想访问该变量的内容。
该变量是一个字符串列表;在 C++ 中,当我执行 TYPEOF(my_sexp) 时,我得到 VECSXP;到目前为止,一切都很好。现在我想将该列表的内容读入 std::vector 中。我尝试了以下想法的多种排列:
SEXP vector_exp = VECTOR_ELT(my_sexp, 0);
int element_count = TRUELENGTH(vector_exp);
for (int i = 0 ; i < element_count ; i++) {
SEXP elem_sexp = VECTOR_ELT(my_sexp, i);
std::string element_string = R_CHAR(elem_sexp);
}
我的问题: - 使用 TRUELENGTH,我可以发生访问冲突。使用 LENGTH,我得到了错误的值。 - 使用 VECTOR_ELT() 访问列表元素会导致访问冲突。 - 我尝试根据 R header 中的结构定义手动检查 my_sexp 的内存布局,但我似乎无法正确进行转换以从中获取有意义的值。
那么,有谁可以大致告诉我如何访问列表的元素吗?或者给我举个例子;或者指出 Rcpp 中完成此类转换的位置?我尝试自己找到最后一点,但没有走得太远 - 看起来 Rcpp 的 wrap() 以某种方式“神奇地”(如一般)处理它。
提前致谢。
最佳答案
我没有花太多时间使用 R 的 C 接口(interface),因为我通常坚持使用 Rcpp,但以下似乎可行:
#include <Rcpp.h>
// [[Rcpp::export]]
void print_list_as_vector(SEXP lst) {
PROTECT(lst);
R_xlen_t n_list = XLENGTH(lst);
R_xlen_t n_elem = 0;
for (R_xlen_t i = 0; i < n_list; i++) {
n_elem += XLENGTH(VECTOR_ELT(lst, i));
}
std::vector<std::string> vs;
vs.reserve(n_elem);
for (R_xlen_t i = 0; i < n_list; i++) {
R_xlen_t nj = XLENGTH(VECTOR_ELT(lst, i));
for (R_xlen_t j = 0; j < nj; j++) {
vs.push_back(CHAR(STRING_ELT(VECTOR_ELT(lst, i), j)));
}
}
for (std::size_t i = 0; i < vs.size(); i++) {
Rcpp::Rcout <<
vs[i] << std::endl;
}
UNPROTECT(1);
}
/*** R
clist <- list(c("a", "b", "c"), c("l", "m", "n", "o", "p"), c("xyz1", "xyz2"))
print_list_as_vector(clist)
#a
#b
#c
#l
#m
#n
#o
#p
#xyz1
#xyz2
unlist(clist)
# [1] "a" "b" "c" "l" "m" "n" "o" "p" "xyz1" "xyz2"
*/
如您所见,这是使用 Rcpp 属性在 R/中进行测试的,但在实际代码中,我尝试坚持使用 C 接口(interface)来复制您的情况。
但是要解决您的问题(尽我所能)-
- 我一直用
XLENGTH
得到SEXP
的长度s,虽然我不能真正说出XLENGTH
之间的差异,LENGTH
和TRUELENGTH
,第一种方法似乎总是能产生预期的结果。 - 我正在使用
VECTOR_ELT(lst, i)
访问VECSXP
中的第 i 个元素lst
. - 鉴于数据/函数的上下文,我知道
VECTOR_ELT(lst, i)
返回STRSXP
- 即字符向量。这个STRSXP
的第j个元素通过STRING_ELT(..., j)
访问,因为这会返回CHARSXP
,我们将其包裹在CHAR
中获得const char*
,添加到std::vector<std::string>
。
不幸的是,似乎没有那么多关于 R 的 C 内部结构的文档,但 Hadley 有一个有用的 reference page here ,如果其他方法都失败了,您可以深入挖掘 the source itself .
关于r - 在 C++ 中嵌入 R : access elements of a VECSXP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31160607/