Rcpp, делая функции доступными для R из DLL - PullRequest
0 голосов
/ 04 ноября 2018

Впервые в C ++, я хотел бы сделать функции, скомпилированные в DLL, доступными в R.

До сих пор мне удавалось сделать это для базовой функции, взяв integer в качестве ввода и вернув ее, выполнив эти шаги в VisualStudio, а затем используя dyn.load из R для загрузки созданного длл.

Однако мои функции C ++ должны будут обрабатывать объекты R data.frame, и я не уверен, как это сделать. Из галереи Rcpp я видел, что Rcpp может включать какие-то переводы между типами данных R и c ++, включая объекты data.frame, но я не знаю, смогу ли я сгенерировать dll, используя Rcpp что я могу затем включить в R, используя dyn.load.

Из этого ответа Дирка Эддельбюттеля представляется возможным создать «динамическую библиотеку» с использованием Rcpp, однако я не смог найти dll, когда попытался сгенерировать пакет с источником .cpp файл с использованием rcpp.package.skeleton(). Функция, для которой я хотел бы получить dll, взята из галереи Rcpp

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
DataFrame modifyDataFrame(DataFrame df) {
  // access the columns
  IntegerVector a = df["a"];
  CharacterVector b = df["b"];

  // make some changes
  a[2] = 42;
  b[1] = "foo";       
  // return a new data frame
  return DataFrame::create(_["a"]= a, _["b"]= b);
}

Я попытался просто вставить этот код в VisualStudio, чтобы попытаться сгенерировать эту DLL, однако у меня появляется ошибка «не удается найти Rcpp.h», которую я вполне ожидал.

Затем я выполнил следующие шаги в RStudio:

  1. Создать новый проект / Пакет
  2. Включить этот исходный файл cpp в качестве исходного файла для этого пакета
  3. include Rcpp и введите Rcpp.package.skeleton("mypackage") пока нет DLL в папках пакета
  4. Попытался собрать пакет в RStudio, перейдя в Build / Install и Restart, но затем я получаю сообщение об ошибке «Сборка R Packages требует установки дополнительных инструментов сборки, вы хотите их установить?» Однако у меня уже установлен RbuildTools 3.4, и когда я нажимаю «ДА» в RStudio, ничего не происходит.

PS: Рад слышать о других методах, но здесь следует использовать формат DLL, если это возможно. Любая информация очень ценится, так как я понятия не имею, как работают Rcpp или C ++

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Вы должны выяснить, почему ваша установка скрыта. Это должно быть легко и это легко. Смотреть:

R> Rcpp::cppFunction('DataFrame modDF(DataFrame df) { IntegerVector a = df["a"]; CharacterVector b = df["b"]; a[2] = 42; b[1] = "foo"; return DataFrame::create(Named("a")=a, Named("b")=b); } ')                  
R> df <- data.frame(a=1:3, b=letters[24:26])                                                                                                                                                                       
R> df                                                                                                                                                                                                              
  a b                                                                                                                                                                                                              
1 1 x                                                                                                                                                                                                              
2 2 y                                                                                                                                                                                                              
3 3 z                                                                                                                                                                                                              
R> modDF(df)                                                                                                                                                                                                       
   a   b                                                                                                                                                                                                           
1  1   x                                                                                                                                                                                                           
2  2 foo                                                                                                                                                                                                           
3 42   z                                                                                                                                                                                                           
R>      

Теперь я, очевидно, не рекомендую писать таким образом в длинных однострочниках. Вы уже на правильном пути настраиваете пакет. Но вам нужно разобраться, что держит ваши инструменты.

И как PS на одну строчку выше с лучшим отступом:

R> Rcpp::cppFunction('DataFrame modDF(DataFrame df) { \
      IntegerVector a = df["a"]; \
      CharacterVector b = df["b"]; \
      a[2] = 42;  \
      b[1] = "foo"; \ 
      return DataFrame::create(Named("a")=a, Named("b")=b); \
    } ')                  
0 голосов
/ 04 ноября 2018

Кажется, работает следующее:

  1. от R, пробег Rcpp.package.skeleton("dfcpp4", cpp_files="modifyDataFrame.cpp"). Второй аргумент необходим для того, чтобы функция modifyDataFrame была доступна из dll с использованием dyn.load.
  2. Из командной строки запускается R CMD build dfcpp4
  3. запускается R CMD check dfcpp4 --no-manual из командной строки.
  4. Файл dll теперь присутствует в папке src-x64

Теперь я могу вызывать эту функцию, используя

dyn.load("dfcpp4/src-x64/dfcpp4.dll")
df <- data.frame(a = c(1, 2, 3),
                 b = c("x", "y", "z"))
.Call("_dfcpp4_modifyDataFrame", df)
   a   b
1  1   x
2  2 foo
3 42   z

Я не понимаю, почему в этом случае следует использовать .Call вместо .C ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...