2015-01-19 2 views
3

Как вы можете использовать некоторую функцию, написанную на C из уровня R, используя данные R. например. использовать функции, как:Как вызвать функцию C из R?

double* addOneToVector(int n, const double* vector) { 
    double* ans = malloc(sizeof(double)*n); 
    for (int i = 0; i < n; ++i) 
     ans[i] = vector[i] + 1 
    return ans; 
} 

в контексте:

x = 1:3 
x = addOneToVector(x) 
x # 2, 3, 4 

ответ

4

Я искал StackOverflow первый, но я заметил, что нет ответа на что здесь.
Основная идея заключается (команды для Linux, но та же идея под другой ОС):

  1. Создать функцию, которая будет принимать только указатели на основные типы и делать все побочные эффекты (возвратов) недействительными. например:

    void addOneToVector(int* n, double* vector) { 
        for (int i = 0; i < *n; ++i) 
         vector[i] += 1.0; 
    } 
    
  2. компилировать исходный файл C, как динамическая библиотека, вы можете использовать R ярлык, чтобы сделать это:

    $ R CMD SHLIB lib.c 
    
  3. Загрузить динамическую библиотеку из R:

    dyn.load("foo.so") 
    
  4. вызовов C с использованием .C Функция R, IE:

    x = 1:3 
    ret_val = .C("addOneToVector", n=length(x), vector=as.double(x)) 
    

Он возвращает список, из которого вы можете получить значение входов после вызова функций, например.

ret_val$x # 2, 3, 4 

Теперь вы можете обернуть его, чтобы использовать его с R проще.

Существует хорошая страница, описывающая весь процесс с большим количеством деталей здесь (также покрытие Fortran):

http://users.stat.umn.edu/~geyer/rc/

+0

Пакет "инлайн", также, удобна в этом контексте: 'AddOne = инлайн :: cfunction (sig = c (n = "integer", vector = "numeric"), body = 'for (int i = 0; i <* n; ++ i) vector [i] + = 1.0;', convention = " .C ")', а затем 'addOne (length (x), as.double (x)) $ vector'. –