cpp4r is now on CRAN!
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
If this post is useful to you I kindly ask a minimal donation on Buy Me a Coffee. It shall be used to continue my Open Source efforts. The full explanation is here: A Personal Message from an Open Source Contributor.
You can send me questions for the blog using this form and subscribe to receive an email when there is a new post.
cpp4r helps you to interact with R objects using C++ code. It is a fork of the cpp11 package with identical syntax and similar goals.
All the documentation is here including the basic, tweaking configurations, and advanced use cases: https://cpp4r.org/.
cpp4r can be used as a replacement for cpp11 in existing or new packages. Think of cpp11 and cpp4r as MySQL and MariaDB: they are almost identical, but cpp4r has some extra features.
Using cpp4r in a package
To add cpp4r to an existing package, install it first:
install.packages("cpp4r", repos = "https://cran.r-project.org") # or the development version: remotes::install_github("pachadotdev/cpp4r")
Then put your C++ files in the src/
directory and add the following to your DESCRIPTION file:
LinkingTo: cpp4r
Then decorate C++ functions you want to expose to R with [[cpp4r::register]]
.
cpp4r is a header only library with no hard dependencies and does not use a shared library, so it is straightforward and reliable to use in packages without fear of compile-time and run-time mismatches.
Alternatively, you can vendor the current installed version of cpp4r headers into your package with cpp4r::vendor()
. This ensures the headers will remain unchanged until you explicitly update them.
Getting started
See the documentation to get started using cpp4r in your scripts, particularly if you are new to C++ programming.
Getting help
Please open an issue or email me. I will do my best to respond before 48 hours.
Examples
Adding dimnames to a matrix on C++ side:
cpp4r::writable::doubles_matrix<> out(2, 2); out(0, 0) = 1; out(0, 1) = 2; out(1, 0) = 3; out(1, 1) = 4; cpp4r::writable::list dimnames(2); dimnames[0] = R_NilValue; // No row names dimnames[1] = cpp4r::strings({"x1", "x2"}); out.attr("dimnames") = dimnames;
Using complex numbers (cannot be done in cpp11):
cpp4r::r_complex zero{0, 0}; cpp4r::r_complex one{1, 1}; cpp4r::r_complex two{2, 2}; cpp4r::r_complex three{3, 3}; cpp4r::writable::complexes x({one, two, three}); cpp4r::writable::complexes y({zero}); auto x_data = x.data(); y = std::move(x); bool y.size() == 3; // true bool y.data() == x_data; // true bool y.is_altrep() == false; // true
Some implicit conversions for lists (cpp11 needs as_sexp()
around scalars for this):
writable::list result; double one = 1.0, two = 2.0, three = 3.0; result.push_back({"one"_nm = one}); result.push_back(named_arg("two", two)); result.push_back({"three"_nm = 3}); writable::list result2(4); int four = 4; bool five = false; const char* six = "six"; std::vector<double> seven = {7.0, 7.1, 7.2}; result2[0] = four; result2[1] = five; result2[2] = six; result2[3] = seven; result2.names() = {"four", "five", "six", "seven"};
Contributing
Contributions are welcome! Please see the internals vignette for details about design choices and coding style.
Code of Conduct
Please note that the cpp4r project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.