32 Interface com códigos compilados

O R pode utilizar códigos compilados em Fortran, C, C++ e Delphi.

Abaixo apresentamos um exemplo simples de como fazer tal interface. Maiores detalhes estão disponíveis no manual Writing R Extensions.

As instruções a seguir são direcionadas para o sistema operacional LINUX. Assume-se que exista um compilador C (por exemplo gcc) disponível no sistema. O mesmo recurso também pode ser usado em outros sistemas operacionais tais como Windows.

Considere o seguinte código em C que gravaremos no arquivo test.c

=======================================================================
#include <math.h>
#include <R.h>
#include <Rmath.h>

void cormatern(int *n, double *uphi, double *kappa, double *ans)
{
 int register i;
 double cte;
 for (i=0; i<*n; i++){
  if (uphi[i]==0) ans[i] = 1;
  else{
   if (*kappa==0.5)
   ans[i] = exp(-uphi[i]);
   else {
    cte = R_pow(2, (-(*kappa-1)))/gammafn(*kappa);
    ans[i] = cte * R_pow(uphi[i], *kappa) * bessel_k(uphi[i],*kappa,1);
}}}}
=======================================================================

Compilamos o código em C na linha de comando do LINUX com uma ferramenta do próprio R. O comando a seguir vai produzir ambos: test.o e test.so

$ R CMD SHLIB test.c
$ R

Uma vez criado o objeto compartilhado test.so (seria um test.dll no Windows) vamos usar uma função do R para acessar funções disponibilizadas por este objeto. No caso de código C mostrado a seguir usamos C(). Para código Fortran usa-se .Fortran() e para C++ .Call. A seguir iniciamos o R e vamos definir uma função "wrapper" em R que vai chamar, passar dados e receber resultados da rotina em C.

"matern" <- function(u, kappa){
  out <- .C("cormatern",
            as.integer(length(u)),
            as.double(u),
            as.double(kappa),
            res = as.double(rep(0,length(u))))$res
  return(out)
}

Depois basta carregar o objeto compartilhado ("shared object") e usar a sua função em R como no exemplo a seguir.

> dyn.load('test.so') 
> matern(0.1, 1) 
> matern(seq(0,1,l=11), 1)