I'm trying to write a cpp11 (the R package) code for an assignment and I have a problem that doesn't happen with Rcpp (another R package).
Both Rcpp and cpp11 allow to use C++ user defined functions in R. For example, with both of them I can write a function to obtain the correlation between two variable, and I would need to define variables such as "x is a vector of doubles", besides a non standard-header such as [[cpp11::register]]
.
I'm adapting from https://github.com/lrberge/fixest/blob/master/src/misc_funs.cpp#L62-L81 besides separate Stan codes, but this is a MWE. However, I couldn't find much examples of adaptation of existing Rcpp codes, besides https://cpp11.r-lib.org/articles/converting.html.
Rcpp
I created a file "rcpp_case.cpp" containing
#include <Rcpp.h>
#include <math.h>
using namespace Rcpp;
using namespace std;
// [[Rcpp::export]]
NumericVector RcppFun(int Q, IntegerVector nbCluster) {
int q;
int sum_cases=0;
IntegerVector start(Q), end(Q);
for(q=0 ; q<Q ; q++){
// the total number of clusters (eg if man/woman and 10 countries: total of 12 cases)
sum_cases += nbCluster(q);
if(q == 0){
start(q) = 0;
end(q) = nbCluster(q);
} else {
start(q) = start(q-1) + nbCluster(q-1);
end(q) = end(q-1) + nbCluster(q);
}
}
return(q);
}
R
In R, I can use the function contained in the cpp file:
library(Rcpp)
sourceCpp("RcppFun.cpp")
RcppFun(Q = c(2L), nbCluster = c(1L,2L,3L))
> RcppFun(Q = c(2L), nbCluster = c(1L,2L,3L))
[1] 0 0
Rcpp -> cpp11
#include <cpp11.hpp>
#include <math.h>
using namespace cpp11;
using namespace std;
[[cpp11::register]]
doubles cpp11_fun(int Q, integers nbCluster) {
int q;
int sum_cases=0;
writable::integers start(Q), end(Q);
for(q=0 ; q<Q ; q++){
// the total number of clusters (eg if man/woman and 10 countries: total of 12 cases)
sum_cases += nbCluster(q);
if(q == 0){
start(q) = 0;
end(q) = nbCluster(q);
} else {
start(q) = start(q-1) + nbCluster(q-1);
end(q) = end(q-1) + nbCluster(q);
}
}
return(q);
}
library(cpp11)
cpp_source("cpp11_fun.cpp")
> cpp_source("cpp11_fun.cpp")
/imputation-model/cpp11_fun.cpp: In function ‘cpp11::doubles cpp11_fun(int, cpp11::integers)’:
/imputation-model/cpp11_fun.cpp:17:29: error: no match for call to ‘(cpp11::integers {aka cpp11::r_vector<int>}) (int&)’
17 | sum_cases += nbCluster(q);
| ^
/imputation-model/cpp11_fun.cpp:19:14: error: no match for call to ‘(cpp11::writable::integers {aka cpp11::writable::r_vector<int>}) (int&)’
19 | start(q) = 0;
| ^
/imputation-model/cpp11_fun.cpp:20:12: error: no match for call to ‘(cpp11::writable::integers {aka cpp11::writable::r_vector<int>}) (int&)’
20 | end(q) = nbCluster(q);
| ^
/imputation-model/cpp11_fun.cpp:20:27: error: no match for call to ‘(cpp11::integers {aka cpp11::r_vector<int>}) (int&)’
20 | end(q) = nbCluster(q);
| ^
/imputation-model/cpp11_fun.cpp:22:14: error: no match for call to ‘(cpp11::writable::integers {aka cpp11::writable::r_vector<int>}) (int&)’
22 | start(q) = start(q-1) + nbCluster(q-1);
| ^
/imputation-model/cpp11_fun.cpp:22:27: error: no match for call to ‘(cpp11::writable::integers {aka cpp11::writable::r_vector<int>}) (int)’
22 | start(q) = start(q-1) + nbCluster(q-1);
| ^
/imputation-model/cpp11_fun.cpp:22:44: error: no match for call to ‘(cpp11::integers {aka cpp11::r_vector<int>}) (int)’
22 | start(q) = start(q-1) + nbCluster(q-1);
| ^
/imputation-model/cpp11_fun.cpp:23:12: error: no match for call to ‘(cpp11::writable::integers {aka cpp11::writable::r_vector<int>}) (int&)’
23 | end(q) = end(q-1) + nbCluster(q);
| ^
/imputation-model/cpp11_fun.cpp:23:23: error: no match for call to ‘(cpp11::writable::integers {aka cpp11::writable::r_vector<int>}) (int)’
23 | end(q) = end(q-1) + nbCluster(q);
| ^
/imputation-model/cpp11_fun.cpp:23:38: error: no match for call to ‘(cpp11::integers {aka cpp11::r_vector<int>}) (int&)’
23 | end(q) = end(q-1) + nbCluster(q);
| ^
/imputation-model/cpp11_fun.cpp:27:11: error: invalid conversion from ‘int’ to ‘SEXP’ {aka ‘SEXPREC*’} [-fpermissive]
27 | return(q);
| ^
| |
| int
In file included from /usr/lib/R/site-library/cpp11/include/cpp11/list.hpp:10,
from /usr/lib/R/site-library/cpp11/include/cpp11/data_frame.hpp:12,
from /usr/lib/R/site-library/cpp11/include/cpp11.hpp:7,
from /imputation-model/cpp11_fun.cpp:1:
/usr/lib/R/site-library/cpp11/include/cpp11/r_vector.hpp:368:41: note: initializing argument 1 of ‘cpp11::r_vector<T>::r_vector(SEXP) [with T = double; SEXP = SEXPREC*]’
368 | inline r_vector<T>::r_vector(const SEXP data)
| ~~~~~~~~~~~^~~~
make: *** [/usr/lib/R/etc/Makeconf:177: /imputation-model/cpp11_fun.o] Error 1
Error: Compilation failed.