Skip to content
Back to skills

Add Rcpp Integration

ASecurity

Añadir integración con Rcpp o RcppArmadillo a un paquete R para código C++ de alto rendimiento. Cubre la configuración, la escritura de funciones C++, la generación de RcppExports, las pruebas del código compilado y la depuración. Usar cuando una función R es demasiado lenta y la elaboración de perfiles confirma un cuello de botella, cuando se necesita interactuar con bibliotecas C/C++ existentes, o al implementar algoritmos (bucles, recursión, álgebra lineal) que se benefician del código com...

  • 31 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added May 29, 2026
ai-agentsgoc++bashgitperformance

Security analysis

A100/100

Scanned May 29, 2026

npx -y skills add pjt222/agent-almanac --skill add-rcpp-integration --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Rcpp Integration?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add Rcpp Integration
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pjt222-add-rcpp-integration/badge)](https://www.skillsdirectory.com/skills/pjt222-add-rcpp-integration)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: add-rcpp-integration
description: >
  Añadir integración con Rcpp o RcppArmadillo a un paquete R para código
  C++ de alto rendimiento. Cubre la configuración, la escritura de funciones
  C++, la generación de RcppExports, las pruebas del código compilado y la
  depuración. Usar cuando una función R es demasiado lenta y la elaboración
  de perfiles confirma un cuello de botella, cuando se necesita interactuar
  con bibliotecas C/C++ existentes, o al implementar algoritmos (bucles,
  recursión, álgebra lineal) que se benefician del código compilado.
locale: es
source_locale: en
source_commit: 6f65f316
translator: claude-opus-4-6
translation_date: 2026-03-16
license: MIT
allowed-tools: Read Write Edit Bash Grep Glob
metadata:
  author: Philipp Thoss
  version: "1.0"
  domain: r-packages
  complexity: advanced
  language: R
  tags: r, rcpp, cpp, performance, compiled-code
---

# Añadir Integración con Rcpp

Integrar código C++ en un paquete R usando Rcpp para operaciones críticas de rendimiento.

## Cuándo Usar

- La función R es demasiado lenta y la elaboración de perfiles confirma un cuello de botella
- Se necesita interactuar con bibliotecas C/C++ existentes
- Implementar algoritmos que se benefician del código compilado (bucles, recursión)
- Añadir RcppArmadillo para operaciones de álgebra lineal

## Entradas

- **Obligatorio**: Paquete R existente
- **Obligatorio**: Función R a reemplazar o complementar con C++
- **Opcional**: Biblioteca C++ externa con la que interactuar
- **Opcional**: Si usar RcppArmadillo (predeterminado: Rcpp simple)

## Procedimiento

### Paso 1: Configurar la Infraestructura de Rcpp

```r
usethis::use_rcpp()
```

Esto:
- Crea el directorio `src/`
- Añade `Rcpp` a LinkingTo e Imports en DESCRIPTION
- Crea `R/packagename-package.R` con `@useDynLib` y `@importFrom Rcpp sourceCpp`
- Actualiza `.gitignore` para los archivos compilados

Para RcppArmadillo:

```r
usethis::use_rcpp_armadillo()
```

**Esperado:** Directorio `src/` creado, DESCRIPTION actualizado con `Rcpp` en LinkingTo e Imports, y `R/packagename-package.R` contiene la directiva `@useDynLib`.

**En caso de fallo:** Si `usethis::use_rcpp()` falla, crear manualmente `src/`, añadir `LinkingTo: Rcpp` e `Imports: Rcpp` a DESCRIPTION, y añadir `#' @useDynLib packagename, .registration = TRUE` y `#' @importFrom Rcpp sourceCpp` al archivo de documentación a nivel de paquete.

### Paso 2: Escribir la Función C++

Crear `src/my_function.cpp`:

```cpp
#include <Rcpp.h>
using namespace Rcpp;

//' Compute cumulative sum efficiently
//'
//' @param x A numeric vector
//' @return A numeric vector of cumulative sums
//' @export
// [[Rcpp::export]]
NumericVector cumsum_cpp(NumericVector x) {
  int n = x.size();
  NumericVector out(n);
  out[0] = x[0];
  for (int i = 1; i < n; i++) {
    out[i] = out[i - 1] + x[i];
  }
  return out;
}
```

Para RcppArmadillo:

```cpp
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

//' Matrix multiplication using Armadillo
//'
//' @param A A numeric matrix
//' @param B A numeric matrix
//' @return The matrix product A * B
//' @export
// [[Rcpp::export]]
arma::mat mat_mult(const arma::mat& A, const arma::mat& B) {
  return A * B;
}
```

**Esperado:** Archivo fuente C++ en `src/my_function.cpp` con anotación `// [[Rcpp::export]]` válida y comentarios de documentación estilo roxygen `//'`.

**En caso de fallo:** Verificar que el archivo usa `#include <Rcpp.h>` (o `<RcppArmadillo.h>` para Armadillo), que la anotación de exportación está en su propia línea directamente encima de la firma de la función, y que los tipos de retorno se corresponden con tipos válidos de Rcpp.

### Paso 3: Generar RcppExports

```r
Rcpp::compileAttributes()
devtools::document()
```

**Esperado:** `R/RcppExports.R` y `src/RcppExports.cpp` generados automáticamente.

**En caso de fallo:** Revisar los errores de sintaxis C++. Asegurarse de que la etiqueta `// [[Rcpp::export]]` está presente encima de cada función exportada.

### Paso 4: Verificar la Compilación

```r
devtools::load_all()
```

**Esperado:** El paquete compila y carga sin errores.

**En caso de fallo:** Revisar la salida del compilador para detectar errores. Problemas frecuentes:
- Cabeceras de sistema faltantes: Instalar las bibliotecas de desarrollo
- Errores de sintaxis: Los mensajes del compilador C++ apuntan a la línea
- Falta el atributo `Rcpp::depends` para RcppArmadillo

### Paso 5: Escribir Pruebas para el Código Compilado

```r
test_that("cumsum_cpp matches base R", {
  x <- c(1, 2, 3, 4, 5)
  expect_equal(cumsum_cpp(x), cumsum(x))
})

test_that("cumsum_cpp handles edge cases", {
  expect_equal(cumsum_cpp(numeric(0)), numeric(0))
  expect_equal(cumsum_cpp(c(NA_real_, 1)), c(NA_real_, NA_real_))
})
```

**Esperado:** Las pruebas pasan, confirmando que la función C++ produce resultados idénticos al equivalente R y gestiona los casos límite (vectores vacíos, valores NA) correctamente.

**En caso de fallo:** Si las pruebas fallan con la gestión de NA, añadir comprobaciones explícitas de NA en el código C++ usando `NumericVector::is_na()`. Si las pruebas fallan con entrada vacía, añadir una cláusula de guarda para vectores de longitud cero al inicio de la función.

### Paso 6: Añadir Script de Limpieza

Crear `src/Makevars`:

```makefile
PKG_CXXFLAGS = -O2
```

Crear `cleanup` en la raíz del paquete (para CRAN):

```bash
#!/bin/sh
rm -f src/*.o src/*.so src/*.dll
```

Hacer ejecutable: `chmod +x cleanup`

**Esperado:** `src/Makevars` establece los indicadores del compilador y el script `cleanup` elimina los objetos compilados. Ambos archivos existen en el nivel raíz del paquete.

**En caso de fallo:** Verificar que `cleanup` tiene permisos de ejecución (`chmod +x cleanup`) y que `Makevars` usa tabulaciones (no espacios) para la sangría si se añaden reglas estilo Makefile.

### Paso 7: Actualizar .Rbuildignore

Asegurarse de que los artefactos compilados se gestionan correctamente:

```
^src/.*\.o$
^src/.*\.so$
^src/.*\.dll$
```

**Esperado:** Los patrones de `.Rbuildignore` evitan que los archivos objeto compilados se incluyan en el tarball del paquete, preservando los archivos fuente y Makevars.

**En caso de fallo:** Ejecutar `devtools::check()` y buscar NOTEs sobre archivos inesperados en `src/`. Ajustar los patrones de `.Rbuildignore` para excluir solo los archivos `.o`, `.so` y `.dll`.

## Validación

- [ ] `devtools::load_all()` compila sin advertencias
- [ ] La función compilada produce resultados correctos
- [ ] Las pruebas pasan para casos límite (NA, vacío, entradas grandes)
- [ ] `R CMD check` pasa sin advertencias de compilación
- [ ] Los archivos RcppExports están generados y confirmados
- [ ] La mejora de rendimiento se confirma con benchmarks

## Errores Comunes

- **Olvidar `compileAttributes()`**: Hay que regenerar RcppExports tras modificar archivos C++
- **Desbordamiento de enteros**: Usar `double` en lugar de `int` para valores numéricos grandes
- **Gestión de memoria**: Rcpp gestiona la memoria automáticamente para los tipos Rcpp; no usar `delete` manualmente
- **Gestión de NA**: C++ no conoce los NA de R. Comprobar con `Rcpp::NumericVector::is_na()`
- **Portabilidad entre plataformas**: Evitar características C++ específicas de una plataforma. Probar en Windows, macOS y Linux.
- **Falta `@useDynLib`**: La documentación a nivel de paquete debe incluir `@useDynLib packagename, .registration = TRUE`

## Habilidades Relacionadas

- `create-r-package` - configuración del paquete antes de añadir Rcpp
- `write-testthat-tests` - probar las funciones compiladas
- `setup-github-actions-ci` - CI debe tener la cadena de herramientas C++
- `submit-to-cran` - los paquetes compilados necesitan verificaciones adicionales de CRAN

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…