문제

R에서 C ++ 라이브러리를 사용하여 C ++ 데이터 구조를 보존하는 가장 좋은 방법은 무엇입니까? 나는 전혀 C ++ 사용자가 아니므로 사용 가능한 접근법의 상대적인 장점에 대해서는 명확하지 않습니다. R-ext 매뉴얼은 C로 모든 C ++ 함수를 포장하는 것을 제안하는 것으로 보이지만, C ++를 통합하는 다른 4 개 또는 5 개 이상의 다른 수단이 존재합니다.

두 가지 방법은 유사한 계보가있는 패키지, RCPP (다량의 오버 플라워 Dirk Eddelbuettel에 의해 유지됨) 및 RCPPTemplate 패키지 (CRAN 모두)입니다. 둘 사이의 차이점은 무엇입니까?

C ++ 및 R의 바인딩에 대한 다른 접근법을 취한다고 주장하는 R Forge에서 사용 가능한 다른 패키지 인 RCPPBind (알 수 없음).

CRAN에서 사용할 수있는 패키지 인라인은 인라인 C/C ++를 허용한다고 주장합니다.이 기능이 내장 기능과 다르다고 확신하지 못하고 코드가 w/r로 인라인이 될 수 있습니다.

그리고 마지막으로 RSWIG가 나타납니다 야생에서 그러나 그것이 얼마나지지되었는지는 확실하지 않습니다. 저자의 페이지 몇 년 동안 업데이트되지 않았습니다.

내 질문은, 이러한 다른 접근법의 상대적인 장점은 무엇입니까? 가장 휴대하고 강력하며 구현하기가 가장 쉬운 것입니다. CRAN에 패키지를 배포 할 계획이라면 어떤 방법을 사용 하시겠습니까?

도움이 되었습니까?

해결책

우선, 면책 조항 : 나는 사용합니다 RCPP 항상. 실제로 (RCPP의 시간에 이름이 바뀌었을 때) rcpptemplate이 이미 고아가되었고 2 년 동안 업데이트되지 않았을 때, 나는 RCPP의 초기 이름으로 그것을 유지하기 시작했습니다 (그 아래에서 기여한 것입니다. rquantlib). 그것은 약 1 년 전이었고, 나는 당신이 Changelog에서 문서화 할 수있는 몇 가지 점진적인 변화를 만들었습니다.

이제 rcpptemplate은 최근에 35 개월 만에 업데이트 나 수정없이 돌아 왔습니다. 흥미로운 새 코드가 포함되어 있지만 거꾸로 호환되지 않으므로 이미 RCPP를 사용한 곳에서는 사용하지 않을 것 같습니다.

rcppbind 내가 확인할 때마다 적극적으로 유지되지 않았습니다. Whit Armstrong에는 또한 템플릿 인터페이스 패키지가 있습니다 Rabstraction.

인라인 완전히 다른 것 : 프로그램을 R 캐릭터 문자열로 '내부'하여 컴파일 / 링크 사이클을 완화시켜 컴파일, 링크 및로드됩니다. 나는 Oleg에게 좋은 RCPP를 지원하는 것에 대해 이야기했습니다.

통음 흥미 롭습니다. Joe Wang은 그곳에서 큰 일을했고 R을 위해 모든 Quantlib를 포장했습니다. 그러나 마지막으로 시도했을 때 R 인테일의 일부 변화로 인해 더 이상 작동하지 않았습니다. SWIG 팀의 누군가에 따르면 Joe는 여전히 작업 할 수 있습니다. SWIG의 목표는 어쨌든 더 큰 라이브러리입니다. 이 프로젝트는 아마도 부흥과 관련이있을 수 있지만 기술적 인 도전이없는 것은 아닙니다.

또 다른 언급은 가야합니다 rinside RCPP와 함께 작동하며 C ++ 응용 프로그램 내부에 R을 포함시킬 수 있습니다.

요약하려면 : RCPP 특히 함수를 추가하려는 소규모 탐색 프로젝트에서는 나에게 잘 작동합니다. 초점은 사용이 용이하며, 항상 함께 일하기에 항상 재미 있지 않은 r 내부를 '숨길'할 수 있습니다. 나는 이메일을 통해 내가 도와 준 다른 많은 사용자들을 알고 있습니다. 그래서 나는 이것을 위해 가고 싶다.

RCPP, Rinside 및 Inline의 몇 가지 예가 있습니다.

편집하다: 따라서 구체적인 예를 살펴 보겠습니다 ( 'r intro'슬라이드가있는 'HPC에서 가져와 Venables와 Ripley에서 가져온 Stephen Milborrow에서 빌린). 작업은 각 위치에 단일 자릿수 만 포함하는 2x2 행렬의 결정 인자의 가능한 모든 조합을 열거하는 것입니다. 이것은 튜토리얼 슬라이드에서 논의하는 것처럼 영리한 벡터화 된 방법 또는 다음과 같이 잔인한 힘으로 수행 할 수 있습니다.

#include <Rcpp.h>

RcppExport SEXP dd_rcpp(SEXP v) {
  SEXP  rl = R_NilValue;        // Use this when there is nothing to be returned.
  char* exceptionMesg = NULL;   // msg var in case of error

  try {
    RcppVector<int> vec(v);     // vec parameter viewed as vector of ints
    int n = vec.size(), i = 0;
    if (n != 10000) 
       throw std::length_error("Wrong vector size");
    for (int a = 0; a < 9; a++)
      for (int b = 0; b < 9; b++)
        for (int c = 0; c < 9; c++)
          for (int d = 0; d < 9; d++)
            vec(i++) = a*b - c*d;

    RcppResultSet rs;           // Build result set to be returned as list to R
    rs.add("vec", vec);         // vec as named element with name 'vec'
    rl = rs.getReturnList();    // Get the list to be returned to R.
  } catch(std::exception& ex) {
    exceptionMesg = copyMessageToR(ex.what());
  } catch(...) {
    exceptionMesg = copyMessageToR("unknown reason");
  }

  if (exceptionMesg != NULL) 
     Rf_error(exceptionMesg);

  return rl;
}

이것을 저장하면 dd.rcpp.cpp 그리고 가지고 있습니다 RCPP 설치 한 다음 간단히 사용하십시오

PKG_CPPFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'`  \
    PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'`  \
    R CMD SHLIB dd.rcpp.cpp

공유 라이브러리를 구축합니다. 우리는 사용 Rscript (또는 r) 묻다 RCPP 헤더 및 라이브러리 위치에 대해. 일단 만들어지면 우리는 다음과 같이 r에서 이것을로드하고 사용할 수 있습니다.

dyn.load("dd.rcpp.so")

dd.rcpp <- function() {
    x <- integer(10000)
    res <- .Call("dd_rcpp", x)
    tabulate(res$vec)
}

마찬가지로 다양한 R 및 C ++ 데이터 유형의 벡터, 행렬 등을 쉽게 보낼 수 있습니다. 이것이 다소 도움이되기를 바랍니다.

편집 2 (약 5 년 후) :

그래서이 대답은 방금 뿌리를 내렸고 따라서 내 줄에 거품이 생겼습니다. ㅏ 많은 내가 쓴 이후로 시간이 지났고 RCPP가 얻었습니다. 많이 기능이 풍부합니다. 그래서 나는 이것을 매우 빨리 썼습니다

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::IntegerVector dd2(Rcpp::IntegerVector vec) {
    int n = vec.size(), i = 0;
    if (n != 10000) 
        throw std::length_error("Wrong vector size");
    for (int a = 0; a < 9; a++)
        for (int b = 0; b < 9; b++)
            for (int c = 0; c < 9; c++)
                for (int d = 0; d < 9; d++)
                    vec(i++) = a*b - c*d;
    return vec;
}

/*** R
x <- integer(10000)
tabulate( dd2(x) )
*/

파일의 코드와 함께 다음과 같이 사용할 수 있습니다. /tmp/dd.cpp

R> Rcpp::sourceCpp("/tmp/dd.cpp")    # on from any other file and path

R> x <- integer(10000)

R> tabulate( dd2(x) )
 [1]  87 132 105 155  93 158  91 161  72 104  45 147  41  96
[15]  72 120  36  90  32  87  67  42  26 120  41  36  27  75
[29]  20  62  16  69  19  28  49  45  12  18  11  57  14  48
[43]  10  18   7  12   6  46  23  10   4  10   4   6   3  38
[57]   2   4   2   3   2   2   1  17
R> 

주요 차이점 중 일부는 다음과 같습니다.

  • 더 간단한 빌드 : 그냥 sourceCpp() 그것; 마지막에 R 테스트 코드를 실행합니다
  • 본격적인 IntegerVector 유형
  • 예외 처리 래퍼가 자동으로 추가됩니다 sourceCpp() 코드 생성기
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top