R

Cómo usar código C++ en R

Rcpp es un paquete disponible en el CRAN que permite emplear código C o C++ en proyectos R. Es una alternativa al la R API más sencilla, por lo que es muy popular. Esto se puede apreciar al comprobar que es utilizado por cerca de 1500 paquetes de los disponibles actualmente en el CRAN. Uno de los principales motivos para usar este paquete es el hecho de que un algoritmo escrito en C o C++ es generalmente más rápido que el mismo escrito en R. Otro motivo es poder utilizar código ya existente en nuestros proyectos de R. En esta entrada se va a explicar cómo usar código C++ en R con el paquete Rcpp. Para ello se va a implementar la sucesión de Fibonacci tanto en R como en C y comparar el rendimiento de ambas soluciones.

Implementación de la sucesión de Fibonacci

La sucesión de Fibonacci se utilizó con anterioridad al explicar la forma de cachear funciones en R con memoise para mejorar el rendimiento de estas. Ya en esa entrada se pudo comprobar que obtener los valores de la serie puede requerir cierto esfuerzo computacional.

Una implementación de esta sucesión en R y C se puede ver en el siguiente bloque de código. En este en primer lugar se carga la librería Rcpp. Posteriormente se implementa la versión de R de la sucesión. Finalmente se utiliza cppFunction para definir la versión en C del algoritmo.

library(Rcpp)

# Definiendo la funcion en R
fibonacci <- function(n) {
  if (n < 2) {
    return(n)
  } else {
    return(fibonacci (n-1) + fibonacci (n-2))
  }
}

# Definiendo la funcion en C
cppFunction('
  int fibonacci_c(int n) {
    if (n < 2) {
      return(n);
    } else {
      return(fibonacci_c(n-1) + fibonacci_c(n-2));
    }
  }'
)

La implementación de R es la misma que ya se utilizó anteriormente en la entrada del paquete memoise. En este código se puede ver lo fácil que es utilizar una función escrita en C con Rcpp. Únicamente se ha de escribir el código y llamar al método cppFunction, creando una función en R con el mismo nombre de la función C. Ahora es fácil comprobar que al llamar al método fibonacci se obtienen el mismo resultado que llamando a fibonacci_c. Por ejemplo, para 10 se obtiene 55, mientras que para 20 el valor devuelto es 6765 en ambos casos.

Comparación del rendimiento

Para comparar el rendimiento de ambas versiones se puede utilizar el paquete rbenchmark. Para ello simplemente se ha de ejecutar ambas versiones con el mismo valor, por ejemplo 25.

library(rbenchmark)
benchmark(fibonacci(25), fibonacci_c(25))[,1:4]
             test replications elapsed relative
1 fibonacci(25) 100 7.394 176.048
2 fibonacci_c(25) 100 0.042 1.000

En los resultados se puede apreciar como la versión de C es mucho más rápida. El tiempo se reduce de 7,394 a 0,042, es decir, el código C es 176 veces más rápido.

El método sourceCpp

Escribir el código C o C++ en una cadena de R puede ser problemático. Para importar directamente archivos con el código se puede utilizar el método sourceCpp. En el archivo simplemente se ha utilizar la etiqueta // [[Rcpp::export]] para indicar las funciones a importar. En estos archivos además es posible incluir bloques de código en R mediante el empleo de comentarios de la forma /*** R ***/.

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
int fibonacci_c(int n) {
  if (n < 2) {
    return(n);
  } else {
    return(fibonacci_c(n-1) + fibonacci_c(n-2));
  }
}

/*** R
fibonacci_c(25)
*/

En este código se puede ver otra vez la implementación de la sucesión de Fibonacci en C. La etiqueta situada antes de la función indica que esta se ha de exportar. Al final del código se puede ver una línea en R que ejecuta el código de la función. Ahora en R simplemente se ha de usar.

sourceCpp('fibonacci.cpp')

Conclusiones

Poder utilizar código C++ en R puede ser muy útil para aumentar el rendimiento de nuestros proyectos. También puede ser de gran ayuda cuando se cuenta con las funciones ya escritas en C o C++. En estas situaciones saber cómo utilizar el paquete Rcpp es importante.

Imágenes: Pixabay (Remaztered Studio)

¿Te ha parecido de utilidad el contenido?

Daniel Rodríguez

Share
Published by
Daniel Rodríguez

Recent Posts

Curiosidad: ¿Por qué usamos p < 0.05? Un umbral que cambió la historia de la ciencia

En casi cualquier análisis estadístico —ya sea en medicina, psicología, economía o ciencia de datos—…

2 días ago

¿Está concentrado el MSCI World? Un análisis con Gini, Lorenz y leyes de potencia

El MSCI World Index suele presentarse como “la ventana al mundo” para quienes invierten en…

4 días ago

Curiosidad: La maldición de la dimensionalidad, o por qué añadir más datos puede empeorar tu modelo

En el mundo del análisis de datos solemos escuchar una idea poderosa: cuantos más datos,…

1 semana ago

Error npm ERR! code EACCES al instalar paquetes en Node.js: Cómo solucionarlo paso a paso

¿Te has encontrado con este error al intentar instalar paquetes con npm? npm ERR! code…

2 semanas ago

Curiosidad: La Paradoja de Simpson, o por qué no siempre debes fiarte de los promedios

En ciencia de datos y estadística, los promedios y porcentajes son herramientas fundamentales para resumir…

2 semanas ago

Copias de seguridad automáticas en SQL Server con rotación de archivos

Las bases de datos son el corazón de casi cualquier sistema de información moderno. Ya…

3 semanas ago

This website uses cookies.