нет соответствующей функции для вызова в rcpp - PullRequest
3 голосов
/ 10 июля 2020

При использовании R cpp я создаю функцию с именем rpois_r cpp и пытаюсь вызвать ее ниже в функции genDataList, возникает ошибка, в которой говорится: «нет соответствующей функции для вызова 'cpprbinom', функция-кандидат не жизнеспособно: нет известного преобразования из 'arma :: ve c' (он же 'Col') в 'R cpp :: NumericVector' (он же 'Vector <14>') для третьего аргумента arma :: ve c cpprbinom (int n, double size, NumericVector prob).

Кто-нибудь может мне помочь, спасибо!

Вот мой код:

//create a random matrix X with covariance matrix sigma
// [[Rcpp::export]]
arma::mat mvrnormArma(const int n, arma::vec mu, const int p, const 
double rho) {

  arma::mat sigma(p, p, arma::fill::zeros);

  for (int i = 0; i < sigma.n_rows; ++i) {
    for (int j = 0; j < sigma.n_cols; ++j) {
      sigma(i,j) = pow(rho, abs((i + 1) - (j + 1)));
    }
  }

  int ncols = sigma.n_cols;
  arma::mat Y = arma::randn(n, ncols);


  return arma::repmat(mu, 1, n).t() + Y * arma::chol(sigma);
}

//create a vector sampled from poisson distribution with mean vector 
//lambda
// [[Rcpp::export]]
arma::vec rpois_rcpp( NumericVector &lambda) {
  int n= lambda.length();
  unsigned int lambda_i = 0;
  IntegerVector sim(n);
  for (unsigned int i = 0; i < n; i++) {
    sim[i] = R::rpois(lambda[lambda_i]);
    // update lambda_i to match next realized value with correct mean
    lambda_i++;

  }
  return  as<arma::vec>(sim);
}

//create a vector sampled from binomial distribution with probability 
vector prob
// [[Rcpp::export]]
arma::vec cpprbinom(int n, double size, NumericVector prob) { 
  NumericVector v = no_init(n);
  std::transform( prob.begin(), prob.end(), v.begin(), [=](double p){ 
      return R::rbinom(size, p); }); 
  return as<arma::vec>(v);}




// [[Rcpp::export]]44
List genDataList(int n, arma::vec& mu, int p, double rho,
             arma::vec& beta, const double SNR, const std::string & 
  Test_case) {

  arma::mat U, V, data, normData, Projection;
  arma::vec s, y, means, noise;

  data = mvrnormArma(n, mu, p, rho);
  normData = arma::normalise(data,2,0);
  arma::svd_econ(U,s,V,normData,"right");
  Projection = V * trans(V);
  beta = Projection * beta;


  if(Test_case == "gaussian")
  {
    means=normData * beta;
    y = means + arma::randn(n) * sqrt(arma::var(means) / SNR);}
  else if (Test_case == "poisson")
  {
    means=exp(normData * beta);
    y = rpois_rcpp(means);}
  else
  {
    means=exp(normData * beta)/(1 + exp(normData * beta));
    y = cpprbinom(n,1,means);}




  List ret;
  ret["data"] = data;
  ret["normData"] = normData;
  ret["V"] = V;
  ret["beta"] = beta;
  ret["y"] = y;
  return ret;

  }

1 Ответ

3 голосов
/ 10 июля 2020

Спасибо за добавление кода. Когда я пытался скомпилировать, я получил ту же ошибку, что и вы, но также ошибка для линии, вызывающей rpois_rcpp()

недопустимая инициализация ссылки для типа 'R cpp :: NumericVector & '

Кажется, что почти все находится в arma, за исключением привязок R и вызовов пространства имен R::, которое принимает двойные, целые и т. Д. c. Кажется, самый простой способ (на мой взгляд) просто взять arma::vec в качестве аргументов:

arma::vec rpois_rcpp( arma::vec &lambda) {
    int n= lambda.n_elem;

и

    arma::vec cpprbinom(int n, double size, arma::vec prob) { 

Вы никогда не используете тот факт, что lambda и prob - это, в частности, Rcpp::NumericVector s, вы просто используете double s из них, поэтому мне это кажется самым простым путем. После этих изменений ваш код отлично компилируется на моей машине. У меня нет никаких тестовых примеров, чтобы убедиться, что они работают так, как вы ожидаете, но я полагаю, что они будут.

...