如何在声明后将 NumericVector 初始化为特定大小?

How to initialize NumericVector to a specific size after it has been declared?

我编写了以下 Rcpp 代码,它编译但没有给出预期的结果。

    // [[Rcpp::export]]
RObject test_1 (Rcpp::NumericVector& x)
{
  NumericVector x1;
  if (x.size() < 5)
  {
    NumericVector x1(x.size()*3);
    for (int ii = 0; ii < x.size(); ii++)
    {
      x1[ii] = sqrt(x[ii]);
    }
  }
  else
  {
    NumericVector x1(x.size()*2);
    for (int ii = 0; ii < x.size(); ii++)
    {
      x1[ii] = sqrt(x[ii]);
    }
  }
  return x1;
}

x1,return 向量在 if 语句外声明,其中 returned 向量 x1 的大小可以变化。但是,如果我用它创建一个新对象的大小声明 NumericVector,但是 returned 在一个空向量中的 x1。

以下代码有效:

// [[Rcpp::export]]
RObject test (const Rcpp::NumericVector& x)
{
  NumericVector x1;
  if (x.size() < 5)
  {
    NumericVector tmp(x.size()*3);
    for (int ii = 0; ii < x.size(); ii++)
    {
      tmp[ii] = sqrt(x[ii]);
    }
    x1 = tmp;
  }
  else
  {
    NumericVector tmp(x.size()*2);
    for (int ii = 0; ii < x.size(); ii++)
    {
      tmp[ii] = sqrt(x[ii]);
    }
    x1 = tmp;
  }
  return x1;
}

在这里我声明了 temp numericvector 然后将 x1 设置为该向量。

我不久前做过这个,知道有一种方法可以在声明 NumericVector 后将其设置为特定大小,但我不记得如何操作了。

编辑:编辑代码和问题以说明如何在 if 语句之前不知道 return 矢量大小。

你可以这样做

RObject test_1 (Rcpp::NumericVector x)
{
    for (int ii = 0; ii < x.size(); ii++)
    {
       x[ii] = sqrt(x[ii]);
    }
    return x;
}

通过传递值,您可以创建一个与原始大小相同的新 NumericVector

如果您不想更改 API,第二个代码可以,但不需要临时变量

 RObject test_1 (const Rcpp::NumericVector& x)
{
    NumericVector x1(x.size());
    for (int ii = 0; ii < x.size(); ii++)
    {
       x1[ii] = sqrt(x[ii]);
    }
    return x1;
}

你可以有条件地 resize 一个 std::vector<double>Rcpp::wrap() 它,像这样:

#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::RObject test_1(const Rcpp::NumericVector& x) {

  std::vector<double> x1;
  if (x.size() < 5) {
    x1.resize(3*x.size());
  } else {
    x1.resize(2*x.size());
  }
  for (int ii = 0; ii < x.size(); ii++) {
    x1[ii] = sqrt(x[ii]);
  }
  return Rcpp::wrap(x1);
}

/*** R

xa <- 1:3
xb <- 1:10

test_1(xa)
# [1] 1.000000 1.414214 1.732051 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

test_1(xb)
#[1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 2.645751 2.828427 3.000000 3.162278 0.000000 0.000000
[13] 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

length(test_1(xa))/length(xa)
#[1] 3
length(test_1(xb))/length(xb) 
#[1] 2

*/

你可以使用这种风格:

NumericVector x;
if (foo)
    x = NumericVector(1);
else
    x = NumericVector(2);

甚至(如果你想避免生成向量的零初始化)

x = static_cast<NumericVector>(no_init(size));

注意写的时候

NumericVector x;
if (foo)
    NumericVector x(1);

您实际上正在创建 两个 NumericVector 个名为 x 的对象 -- 一个在顶级范围内,一个在范围内if 语句。

也就是说,当你写的时候值得理解

NumericVector x;

你实际上是在创建一个对象,而不仅仅是声明一个对象(这只适用于内置类型,例如int)。因此,当您编写 NumericVector x 时,x 实际上是使用零参数 NumericVector 构造函数(创建长度为 0 的数字向量)

进行默认构造的