Site icon R-bloggers

cpp4r is now on CRAN!

[This article was first published on https://pacha.dev/blog, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
< !DOCTYPE html> < charset="utf-8"> < http-equiv="X-UA-Compatible" content="IE=edge"> < name="viewport" content="width=device-width, initial-scale=1.0"> pacha.dev/blog < !-- MathJax Configuration --> < !-- Smart header: libraries detected based on content --> < !-- File: /tmp/tmp.Mj5RCO4bUv/index.html -->
  • < !-- DEBUG: Found sourceCode --> < !-- Load custom CSS after any library CSS to ensure proper precedence -->
  • < header class="site-top">

    Mauricio “Pachá” Vargas Sepúlveda

    Blog with notes about R, Shiny, SQL, Python, Linux and C++. This blog is listed on R-Bloggers.

    HOME 🏠
    < !-- categories are printed below this--> < nav class="sidebar-nav">

    Categories

    < header id="title-block-header" class="quarto-title-block default">

    cpp4r is now on CRAN!

    The cpp4r package aims to help users to interact with R objects using C++ code.
    Author

    Mauricio “Pachá” Vargas S.

    Published

    October 16, 2025

    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.

    < section id="using-cpp4r-in-a-package" class="level2">

    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.

    < section id="getting-started" class="level2">

    Getting started

    See the documentation to get started using cpp4r in your scripts, particularly if you are new to C++ programming.

    < section id="getting-help" class="level2">

    Getting help

    Please open an issue or email me. I will do my best to respond before 48 hours.

    < section id="examples" class="level2">

    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"};
    < section id="contributing" class="level2">

    Contributing

    Contributions are welcome! Please see the internals vignette for details about design choices and coding style.

    < section id="code-of-conduct" class="level2">

    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.

    < footer>

    Loading…

  • < !-- Load shared sidebar -->
    To leave a comment for the author, please follow the link and comment on their blog: https://pacha.dev/blog.

    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.
    Exit mobile version