вызов пользовательской функции R из C ++ с использованием Rcpp

У меня есть код R с кучей определяемых пользователем функций R. Я пытаюсь заставить код работать быстрее, и, конечно же, лучший вариант - использовать Rcpp. В моем коде есть функции, которые вызывают друг друга. Следовательно, если я напишу некоторые функции на C ++, я смогу вызывать и запускать некоторые из моих функций R в моем коде на C ++. В простом примере рассмотрим приведенный ниже код на R:

mySum <- function(x, y){
 return(2*x + 3*y)
}
x <<- 1
y <<- 1

Теперь рассмотрим код C ++, в котором я пытаюсь получить доступ к указанной выше функции:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
int mySuminC(){
 Environment myEnv = Environment::global_env();
 Function mySum = myEnv["mySum"];
 int x = myEnv["x"];
 int y = myEnv["y"];
 return wrap(mySum(Rcpp::Named("x", x), Rcpp::Named("y", y)));
 }

Когда я отправляю файл в R с помощью встроенной функции sourceCpp (), я получаю сообщение об ошибке:

 "invalid conversion from 'SEXPREC*' to int

Может ли кто-нибудь помочь мне в отладке кода? Насколько эффективен мой код? Можно ли резюмировать? Есть ли лучшая идея использовать функцию mySum, чем то, что я сделал в своем коде?

Большое спасибо за вашу помощь.


person Sam    schedule 20.01.2014    source источник
comment
@DirkEddelbuettel, с большим уважением, я не согласен - ссылка выше касается совершенно другой проблемы.   -  person Sam    schedule 20.01.2014
comment
В нем говорится, что а) легко вызвать функцию, б) что вызов функции R из C ++ не быстрее, чем из R (и было неясно, поняли ли вы это) и в) проблема с преобразованием int является не связанная проблема новичка.   -  person Dirk Eddelbuettel    schedule 20.01.2014


Ответы (1)


Вы заявляете, что функция должна возвращать int, но используете wrap, который указывает, что возвращаемый объект должен быть SEXP. Более того, вызов функции R из Rcpp (через Function) также возвращает SEXP.

Вы хотите что-то вроде:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP mySuminC(){
  Environment myEnv = Environment::global_env();
  Function mySum = myEnv["mySum"];
  int x = myEnv["x"];
  int y = myEnv["y"];
  return mySum(Rcpp::Named("x", x), Rcpp::Named("y", y));
}

(или оставьте функцию return как int и используйте as<int> вместо wrap).

Тем не менее, это своего рода неидиоматический Rcpp код. Помните, что вызов функций R из C ++ по-прежнему будет медленным.

person Kevin Ushey    schedule 20.01.2014
comment
Ага. Здесь есть несколько предыдущих ответов, подтверждающих то же самое. - person Dirk Eddelbuettel; 20.01.2014
comment
@DirkEddelbuettel и Кевин, у меня есть еще один вопрос относительно этого поста. Рассмотрим типичную программу на C ++, в которой есть набор функций, объявленных вне блока int main () и используемых внутри блока. Теперь рассмотрим аргумент body в cxxfunction (), для меня body отчасти похоже на то, что находится внутри блока int main (). Мой вопрос в том, где объявить те функции, которые находятся вне main () и используются внутри него в cxxfunction ()? - person Sam; 20.01.2014
comment
@DirkEddelbuettel, конечно. - person Sam; 20.01.2014
comment
как получить возвращаемые значения из функции R? На самом деле stackoverflow.com/a/21225890/9113303 здесь мы вызываем функцию R mySum. Итак, мы должны получить возвращаемое значение return (2 * x + 3 * y). Но в результате я получаю Rcpp :: sourceCpp ('Desktop / cuda_pgm_cpp / mySum.cpp') во время работы в R studio. - person 9113303; 27.06.2018