rigraphrcpprcpp11

Calling igraph from within Rcpp


As a part of utilizing network data drawn at random before further processing, I am trying to call a couple of functions from the igraph package at the beginning of each iteration. The code I use is as follows:

#define ARMA_64BIT_WORD
#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins(cpp11)]]
using namespace Rcpp;

using arma::sp_mat;

// [[Rcpp::export]]
sp_mat adj_mat(int n, double p) {

  Environment igraph("package:igraph");
  Function game_er = igraph["erdos.renyi.game"];
  Function get_adjacency = igraph["get.adjacency"];

  List g = game_er(Named("n", n), Named("p", p));

  NumericMatrix A_m = get_adjacency(Named("g", g));

  sp_mat A = as<sp_mat>(A_m);

  return A;
}


/*** R
set.seed(20130810)
library(igraph)

adj_mat(100, 0.5)
*/

So, while the C++ compiles without warnings, the following error is thrown:

> sourceCpp("Hooking-R-in-cpp.cpp")

> set.seed(20130810)

> library(igraph)

> adj_mat(100, 0.5)
Error in adj_mat(100, 0.5) : 
  Not compatible with requested type: [type=S4; target=double].

From the error it looks like I am passing a S4 class to a double? Where is the error?


Solution

  • You were imposing types in the middle of your C++ functions that did not correspond to the representation, so you got run-time errors trying to instantiate them.

    The version below works. I don't know igraph well enough to suggest what else you use to store the first return; for the S4 you can use the dgCMatrix matrix but S4 is an ok superset.

    #include <RcppArmadillo.h>
    
    // [[Rcpp::depends(RcppArmadillo)]]
    // [[Rcpp::plugins(cpp11)]]
    using namespace Rcpp;
    
    using arma::sp_mat;
    
    // [[Rcpp::export]]
    sp_mat adj_mat(int n, double p) {
    
      Environment igraph("package:igraph");
      Function game_er = igraph["erdos.renyi.game"];
      Function get_adjacency = igraph["get.adjacency"];
    
      SEXP g = game_er(Named("n", n), Named("p", p));
    
      S4 A_m = get_adjacency(Named("g", g));
    
      sp_mat A = as<sp_mat>(A_m);
    
      return A;
    }
    
    /*** R
    set.seed(20130810)
    library(igraph)
    
    adj_mat(100, 0.5)
    */