2017-04-13 50 views
1

我想將R函數轉換爲Rcpp,一個簡單的測試代碼如下,但我不知道如何處理設置的參數默認爲NULL。Rcpp:如何獲取Rcpp :: Nullable NumericVector的大小

test<- function(t=NULL,tmax=NULL,tmin=NULL){ 
    if(is.null(t)){ 
    yout=(tmax-tmin)*(tmin+tmax) 
    }else{ 
    yout=2*t 
    } 
    return(yout) 
} 

test(tmax=1:3,tmin=0:2) 




    // [[Rcpp::export]] 
    NumericVector cpptest(Rcpp::Nullable<Rcpp::NumericVector> t=R_NilValue, 
          Rcpp::Nullable<Rcpp::NumericVector> tmax=R_NilValue, 
          Rcpp::Nullable<Rcpp::NumericVector> tmin=R_NilValue){ 
     int N=0; 
     if(t.isNotNull()) { 
     N=t.size(); /* which show a error*/ 
     }else{ 
     N=tmax.size(); /* which show a error*/ 
     } 
     NumericVector yout=NumericVector(N); 

     if(t.isNotNull()) { 
     for(i=0;i<N,i++){ 
      yout[i]=2*t[i] 
     } 
     }else{ 
     for(i=0;i<N,i++){ 
      yout[i]=(tmax[i]-tmin[i])*(tmin[i]+tmax[i]) 
     } 
     } 
     return(yout) 
    } 

回答

3

而不是呼叫,例如, .size()直接在對象上,因爲你在這裏做 - N = t.size(); - 你需要將它轉換爲基礎類型。例如,

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
int nullable_size(Nullable<NumericVector> x_ = R_NilValue) 
{ 
    if (x_.isNotNull()) { 
     NumericVector x(x_.get()); 
     return x.size(); 
    } 
    warning("argument x_ is NULL"); 
    return -1; 
} 

/*** R 

nullable_size(rnorm(5)) 
# [1] 5 

nullable_size(NULL) 
# [1] -1 
# Warning message: 
# In .Primitive(".Call")(<pointer: 0x000000006aa417a0>, x_) : 
# argument x_ is NULL 

*/ 

正如德克指出,使用.get()不是絕對必要在這裏 - 使用NumericVector x(x_);將調用Nullable<>::operator SEXP()和同樣出色的工作。


此外,請在未來更好地設置您的代碼格式。

+2

正確的答案,以及格式非常正確的提示。這只是缺乏你想要的大小的_instantiation_。我更喜歡[這個更簡單的形式](https://github.com/aliceyiwang/mvabund/blob/master/src/Rinterface.cpp#L52-L53)。它與'NumericVector'和其他'SEXP'兼容類型的工作方式相同。 –