Search code examples
rrcpp

Rcpp trouble importing 'hessian' from R package 'numDeriv'


I am trying to build a package that uses the function 'hessian' from the package 'numDeriv'. However, when I build the package and run the code I get the error

Cannot convert object to an environment: [type=character; target=ENVSXP].

Example simplified Rcpp code below

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
#include <stdio.h> 
#include<armadillo>
using namespace Rcpp;
using namespace std;


double testfunc(double X){

  return pow(X+1,2);

}


double hessian_rcpp(double X){

  Rcpp::Environment numDeriv("package:numDeriv");
  Rcpp::Function hessian = numDeriv["hessian"];

  Rcpp::List hessian_results = hessian(
  Rcpp::_["func"] = Rcpp::InternalFunction(testfunc), 
    Rcpp::_["x"] = X);

  arma::vec out = Rcpp::as<arma::vec>(hessian_results[0]);

  return out[0];
}

// [[Rcpp::export]]
double returnhess(double X){

  double out = hessian_rcpp(X);

  return out;

}

Then after building the package running the following R code results in the error.

library(test)
returnhess(X=3)
Error in returnhess(X = 3) : 
Cannot convert object to an environment: [type=character; target=ENVSXP].

My NAMESPACE is

useDynLib(test, .registration=TRUE)
importFrom(Rcpp, evalCpp)
exportPattern("^[[:alpha:]]+")

My DESCRIPTION is

Package: test
Type: Package
Title: What the Package Does (Title Case)
Version: 0.1.0
Author: Who wrote it
Maintainer: The package maintainer <yourself@somewhere.net>
Description: More about what it does (maybe more than one line) Use four spaces when indenting paragraphs within the Description.
License: What license is it under?
Imports: Rcpp, RcppArmadillo, numDeriv
LinkingTo: Rcpp, RcppArmadillo, numDeriv
Encoding: UTF-8
LazyData: true

My R version is 3.5.1, RStudio version is 1.1.456, Rcpp version is 0.12.19, RcppArmadillo version is 0.9.100.5.0, numDeriv version is 2016.8.1. My operating system is windows 10.

I was able to successfully import 'optimize' from the R package 'stats' with an analogous approach. Example simplified code below

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
#include <stdio.h> 
#include<armadillo>
using namespace Rcpp;
using namespace std;

  double testfunc(double X){

  return pow(X+1,2);

}

double optim_rcpp(){

  Rcpp::Environment stats("package:stats");
  Rcpp::Function optimize = stats["optimize"];

  Rcpp::List opt_results = optimize(
  Rcpp::_["f"] = Rcpp::InternalFunction(testfunc), 
  Rcpp::_["lower"] = -10, 
  Rcpp::_["upper"] =  10);

  arma::vec out = Rcpp::as<arma::vec>(opt_results[0]);

  return out[0];
}

// [[Rcpp::export]]
double returnoptim(){

  double out = optim_rcpp();

  return out;

}

Same NAMESPACE and DESCRIPTION as above

Then running the following R code works

returnoptim()
[1] -1

Solution

  • As a workaround you can add

     Depends:numDeriv
    

    to your DESCRIPTION. This ensures that the numDeriv package is loaded together with your package.

    BTW: I would refrain from using using namespace Rcpp; in a package. And I would never use using namespace std;. I cannot think of a good reason to use #include <stdio.h> and #include<armadillo>is unnecessary when RcppArmadillo is used.