03 - Converting between R and Armadillo types

Adapted from the official Armadillo documentation.

armadillo4r provides a set of conversion functions, declared across armadillo4r/wrappers/matrices.hpp, armadillo4r/wrappers/vectors.hpp, armadillo4r/wrappers/cubes.hpp, and armadillo4r/wrappers/fields.hpp, and all automatically available after including <armadillo4r.hpp>. This vignette documents every function and shows a minimal C++ example for each group.

R to Armadillo

Matrices

R matrices are represented in cpp4r as doubles_matrix<> (numeric) or integers_matrix<> (integer). The following functions convert them to Armadillo dense matrices:

| cpp4r input | Function | Armadillo output | Notes | |-------------|----------|-----------------|-------| | doubles_matrix<> | as_Mat(x) / as_mat(x) | Mat<double> | as_mat() is a lowercase alias | | integers_matrix<> | as_Mat(x) / as_mat(x) | Mat<int> | same alias applies | | integers_matrix<> | as_imat(x) | imat (Mat<sword>) | signed integer matrix | | integers_matrix<> | as_umat(x) | umat (Mat<uword>) | unsigned integer matrix; copies element-by-element | | doubles_matrix<> | as_fmat(x) | fmat (Mat<float>) | narrows double to float |

#include <cpp4r.hpp>
#include <armadillo4r.hpp>

using namespace arma;
using namespace cpp4r;

[[cpp4r::register]]
doubles_matrix<> mat_demo_(const doubles_matrix<>& x,
                           const integers_matrix<>& xi) {
  mat    A  = as_Mat(x);    // double matrix
  imat   Ai = as_imat(xi);  // signed int matrix
  umat   Au = as_umat(xi);  // unsigned int matrix
  fmat   Af = as_fmat(x);   // float matrix

  // use A, Ai, Au, Af ...
  return as_doubles_matrix(A * A.t());
}
x <- matrix(c(1.5, 2.5, 3.5, 4.5), nrow = 2)
xi <- matrix(1:4, nrow = 2)
mat_demo_(x, xi)

Vectors

R vectors (doubles / integers) map to Armadillo column vectors:

| cpp4r input | Function | Armadillo output | Notes | |-------------|---------------------------|-----------------------|--------------------------------------------| | doubles | as_Col(x) / as_col(x) | Col<double> (vec) | as_col() is a lowercase alias | | integers | as_Col(x) / as_col(x) | Col<int> | same alias applies | | integers | as_uvec(x) | uvec (Col<uword>) | copies element-by-element (no reinterpret) |

[[cpp4r::register]]
doubles vec_demo_(const doubles& y, const integers& yi) {
  vec  v  = as_Col(y);    // double column vector
  uvec vu = as_uvec(yi);  // unsigned int column vector

  // use v, vu ...
  return as_doubles(v % v);   // element-wise square
}
vec_demo_(c(1.0, 2.0, 3.0), 1:3)

Cubes

R has no native quasi third-order tensors ("3D matrices") that maps directly onto Armadillo's memory layout. armadillo4r therefore represents a cube on the R side as a list of matrices, where every element is a matrix of the same dimensions. Slice s of the Armadillo cube corresponds to element s + 1 of the R list (R is 1-indexed).

The most commonly used cube typedefs are:

| Typedef | Equivalent | Element type | |---------|-----------|--------------| | cube / dcube | Cube<double> | double | | fcube | Cube<float> | float | | icube | Cube<sword> | long long (signed, platform-dependent) | | ucube | Cube<uword> | unsigned int | | cx_cube / cx_dcube | Cube<cx_double> | std::complex<double> |

| cpp4r input | Function | Armadillo output | Notes | |-------------|----------|-----------------|-------| | list of doubles_matrix<> | as_Cube(x) / as_cube(x) | Cube<double> (cube) | as_cube() is a lowercase alias | | list of integers_matrix<> | as_icube(x) | Cube<int> | note: assigns to Cube<int>, not icube (Cube<sword>) |

Both functions throw std::runtime_error if the list is empty or any matrix has dimensions different from the first.

[[cpp4r::register]]
doubles_matrix<> cube_col_means_(const list& slices) {
  cube C = as_Cube(slices);   // list of doubles_matrix<> -> cube

  mat result(C.n_slices, C.n_cols);
  for (uword s = 0; s < C.n_slices; ++s) {
    result.row(s) = mean(C.slice(s), 0);  // column means of each slice
  }

  return as_doubles_matrix(result);
}
slices <- list(
  matrix(1:6, nrow = 2), # slice 1
  matrix(7:12, nrow = 2), # slice 2
  matrix(13:18, nrow = 2) # slice 3
)
cube_col_means_(slices)

Fields

An Armadillo field<object_type> stores arbitrary objects (matrices, vectors, strings, …) in a matrix-like or cube-like layout. Unlike Cube, the elements of a field do not need to have the same size — each element is an independent object.

Tip: when all matrices share the same dimensions, prefer Cube over field<mat> because Cube is more memory-efficient and faster.

On the R side a field is always represented as a plain list (or strings for field<std::string>). Element i of the Armadillo field (0-indexed) corresponds to element i + 1 of the R list (1-indexed).

| cpp4r input | Function | Armadillo output | Notes | |-------------|----------|-----------------|-------| | list of doubles_matrix<> | as_field_mat(x) | field<mat> | matrices may differ in size | | list of integers_matrix<> | as_field_imat(x) | field<imat> | matrices may differ in size | | list of doubles | as_field_vec(x) | field<vec> | vectors may differ in length | | strings | as_field_str(x) | field<std::string> | |

All four functions throw std::runtime_error if the input list is empty.

[[cpp4r::register]]
list field_mat_demo_(const list& mats) {
  // Ragged list of matrices -> field<mat>
  field<mat> F = as_field_mat(mats);

  // Normalise each matrix independently
  for (uword i = 0; i < F.n_elem; ++i) {
    F(i) = normalise(F(i));  // L2-normalise columns
  }

  // field<mat> -> list of doubles_matrix<>
  return as_doubles_matrix_field(F);
}
mats <- list(
  matrix(1:6, nrow = 2), # 2x3 matrix
  matrix(1:12, nrow = 4) # 4x3 matrix  (different nrow!)
)
field_mat_demo_(mats)

Armadillo to R

Matrices

| Armadillo input | Function | cpp4r output | |----------------|----------|-------------| | Mat<double> / mat / fmat | as_doubles_matrix(A) | doubles_matrix<> | | Mat<int> / imat / umat | as_integers_matrix(A) | integers_matrix<> | | Mat<cx_double> / cx_mat | as_complexes_matrix(A) | complexes_matrix<> |

[[cpp4r::register]]
doubles_matrix<> mat_out_demo_(const doubles_matrix<>& x) {
  mat A = as_Mat(x);
  return as_doubles_matrix(A.t() * A);  // mat -> doubles_matrix<>
}
x <- matrix(1:9, nrow = 3) * 1.0
mat_out_demo_(x)

Vectors

| Armadillo input | Function | cpp4r output | |----------------|----------|-------------| | Col<double> / vec | as_doubles(v) | doubles | | Col<int> / ivec | as_integers(v) | integers | | uvec | as_integers(v) | integers |

[[cpp4r::register]]
doubles vec_out_demo_(const doubles& y) {
  return as_doubles(normalise(as_Col(y)));  // vec -> doubles
}
vec_out_demo_(c(3.0, 4.0)) # should give c(0.6, 0.8)

Cubes

| Armadillo input | Function | cpp4r output | |----------------|----------|-------------| | Cube<double> / cube | as_doubles_matrix_list(C) | list of doubles_matrix<> | | Cube<int> / icube | as_integers_matrix_list(C) | list of integers_matrix<> | | ucube | as_integers_matrix_list(C) | list of integers_matrix<> |

Slice s of the cube becomes element s + 1 of the returned R list.

[[cpp4r::register]]
list random_cube_(const int n_rows, const int n_cols, const int n_slices) {
  cube C(n_rows, n_cols, n_slices, fill::randn);
  return as_doubles_matrix_list(C);  // cube -> list of doubles_matrix<>
}
set.seed(42)
result <- random_cube_(3L, 4L, 2L)

length(result) # 2  (one element per slice)
dim(result[[1]]) # 3 4

Fields

| Armadillo input | Function | cpp4r output | |----------------|----------|--------------| | field<mat> | as_doubles_matrix_field(F) | list of doubles_matrix<> | | field<imat> | as_integers_matrix_field(F) | list of integers_matrix<> | | field<vec> | as_doubles_field(F) | list of doubles | | field<std::string> | as_strings_field(F) | strings |

Element i of the field (0-indexed) becomes element i + 1 of the returned R list (1-indexed). Because field elements may differ in size, the returned list is potentially ragged.

[[cpp4r::register]]
list build_field_(const integers& sizes) {
  // Build a field<vec> where each vector has a different length
  field<vec> F(sizes.size());

  for (uword i = 0; i < F.n_elem; ++i) {
    F(i) = randn<vec>(sizes[static_cast<int>(i)]);  // random vector of length sizes[i]
  }

  return as_doubles_field(F);  // field<vec> -> list of doubles
}
build_field_(c(3L, 5L, 2L)) # list of three vectors of lengths 3, 5, 2

Generic conversion with cpp4r::as_sexp()

For cases where the return type is determined at compile time, cpp4r::as_sexp() provides a single generic entry point that dispatches to the appropriate conversion based on the Armadillo type:

| Armadillo input | as_sexp() output | |----------------|--------------------| | vec / fvec | doubles | | ivec / uvec | integers | | mat / fmat | doubles_matrix<> | | imat / umat | integers_matrix<> | | rowvec / frowvec | doubles_matrix<> (1-row matrix) | | irowvec / urowvec | integers_matrix<> (1-row matrix) |

[[cpp4r::register]]
SEXP as_sexp_demo_(const doubles& y) {
  return cpp4r::as_sexp(arma::sort(as_Col(y)));  // vec -> doubles (dispatched automatically)
}
as_sexp_demo_(c(3.0, 1.0, 2.0)) # returns c(1, 2, 3)

References



Try the armadillo4r package in your browser

Any scripts or data that you put into this service are public.

armadillo4r documentation built on Aug. 23, 2026, 5:07 p.m.