我很难理解如何使用Rcpp::XPtr.

我想将整数向量的R列表传递给C++,将其转换为std::vector<std::unordered_set<int> >,并将其作为Rcpp::XPtr返回给R,然后在后面的C++函数中重复使用它.

// [[Rcpp::plugins(openmp)]]
#include <Rcpp.h>
#include <vector>
#include <unordered_set>
#include <omp.h>
#include <cstddef>

// [[Rcpp::export]]
Rcpp::XPtr<std::vector<std::unordered_set<int> > > convert_to_cpp_type(Rcpp::List& x) {
  std::size_t x_size = x.size();
  std::vector<std::unordered_set<int> > y(x_size);

  for(std::size_t i = 0; i < x_size; ++i) {
    Rcpp::IntegerVector x_i = x[i];
    y[i].insert(x_i.begin(), x_i.end());
  }

  Rcpp::XPtr<std::vector<std::unordered_set<int> > > z(y);
  return z;
}

// [[Rcpp::export]]
Rcpp::NumericVector use_xptr(SEXP a) {
  Rcpp::XPtr<std::vector<std::unordered_set<int> > > b(a);
  std::size_t b_size = (*b).size();
  std::vector<double> c (b_size);  

  #pragma omp parallel for num_threads(10)
  for(std::size_t i = 0; i < b_size; ++i) {
    c[i] = example_function((*b)[i]);
  }

  return Rcpp::wrap(c);
}

这段代码不能编译,但它应该提供了我的目标是做什么的 idea .第二个函数中的a是第一个函数导出的XPtr.

此代码中应该有多个错误.然而,即使在浏览了数小时的Stack Overflow、RCPP网站和各种其他站点之后,我也不知道如何正确地实现它.

推荐答案

您的第一个函数没有编译,因为XPtr构造函数需要一个原始指针,而不是std::vector.然而,返回的指针将比无用更糟糕,因为它指向的是函数返回后超出范围的局部变量.如果您稍后try 使用它,则您的会话将崩溃.

以下函数将返回指向std::vector<std::unordered_set>>的有效指针:

library(Rcpp)

cppFunction("

Rcpp::XPtr<std::vector<std::unordered_set<int> > > 
convert_to_cpp_type(Rcpp::List x) {

  typedef std::vector<std::unordered_set<int>> obj;
  std::size_t x_size = x.size();
  obj* y = new obj;

  for(std::size_t i = 0; i < x_size; ++i) {
    Rcpp::IntegerVector x_i = x[i];
    std::unordered_set s(x_i.begin(), x_i.end());
    y->push_back(s);
  }

  Rcpp::XPtr<obj> z(y);
  return z;
  
}")

要获取指针索引的对象的内容,我们需要再次构建一个R列表:

cppFunction("

Rcpp::List use_xptr(SEXP a) {

  Rcpp::XPtr<std::vector<std::unordered_set<int>>> b(a);
  Rcpp::List out;
  for(std::size_t i = 0; i < b->size(); ++i) {
    Rcpp::NumericVector x_i((*b)[i].begin(), (*b)[i].end());
    out.push_back(x_i);
  }
  return out;
  
}")

为了完整起见,让我们创建一个可以从R调用的函数来修改我们的C++对象(因为我们没有example_function

cppFunction("

void do_stuff(Rcpp::XPtr<std::vector<std::unordered_set<int>>> x) {

  x->push_back(std::unordered_set<int> {0, 1, 2, 3});
  return;

}")

现在在R中,我们可以做:

x <- list(1:10, 3:7)

x
#> [[1]]
#>  [1]  1  2  3  4  5  6  7  8  9 10
#> 
#> [[2]]
#> [1] 3 4 5 6 7

xptr <- convert_to_cpp_type(x)

xptr
#> <pointer: 0x0000023659ab57c0>

do_stuff(xptr)

use_xptr(xptr)
#> [[1]]
#> [1] 10  9  8  7  6  5  4  3  2  1
#> 
#> [[2]]
#> [1] 7 6 5 4 3
#> 
#> [[3]]
#> [1] 3 2 1 0

这似乎是一种不必要的困难方式.在我看来,将列表发送到C++,让它执行您想要的所有计算,并返回结果,似乎更有意义.在这里,指针并不能真正帮助您.

R相关问答推荐

使用scale_x_continuous复制ggplot 2中的离散x轴

r—绘制相交曲线

当两个图层映射到相同的美学时,隐藏一个图层的图例值

如何直接从Fortran到R的数组大小?

计算时间段的ECDF(R)

在R中,如何将变量(A,B和C)拟合在同一列中,如A和B,以及A和C在同一面板中?

在df中保留原始变量和新变量

R中插入符号训练函数的中心因子和尺度因子预测

一小时满足条件的日期的 Select

使用带有OR条件的grepl过滤字符串

将一个字符串向量调整为与其他字符串向量完全相同的大小

R中1到n_1,2到n_2,…,n到n_n的所有组合都是列表中的向量?

有没有办法使用ggText,<;Sub>;&;<;sup>;将上标和下标添加到同一元素?

按组计算列中1出现的间隔年数

如何从向量构造一系列双边公式

在纵向数据集中创建新行

判断函数未加载R中的库

根据r中每行中的日期序列,使用列名序列创建新列

以R表示的NaN值的IS.NA状态

从两个数据帧中,有没有办法计算R中一列的唯一值?