Rcpp将长度为0(NULL)的向量传递给CPPP函数
我有一个Rcpp将长度为0(NULL)的向量传递给CPPP函数,r,rcpp,R,Rcpp,我有一个cpp函数,输入向量ints,例如: library(Rcpp) cppFunction('double test2(NumericVector ints) { return 42; }') 如果传递长度至少为1的向量,则输出正确: > test2(1) [1] 42 > test2(1:10) [1] 42 对于长度为0的输入,我得到: > test2(c()) Error: not compatible with
cpp函数
,输入向量ints
,例如:
library(Rcpp)
cppFunction('double test2(NumericVector ints) {
return 42;
}')
如果传递长度至少为1的向量,则输出正确:
> test2(1)
[1] 42
> test2(1:10)
[1] 42
对于长度为0的输入,我得到:
> test2(c())
Error: not compatible with requested type
有没有办法将长度为0或更大的向量传递给我的函数?即,我的预期产出是:
> test2_expectedoutput(c())
[1] 42
我知道我可以在R中通过先签入R并调用不同版本的函数来控制它,但我希望避免这种情况。我希望有一些简单的解决方案,因为在cpp中,如果我正确理解什么是NumericVector zero,我也可以有长度为0的NumericVector
代码>可以。我能找到的唯一相关问题是 调用c()
生成的NULL
不是numeric
向量。这会在调用test2
时生成错误。您可以构建长度为0到numeric
的数值向量:
#check what `c()` does
str(c())
# NULL
# now we try numeric(0)
test2(numeric(0))
#[1] 42
作为建议,我认为不应该直接调用C
、Fortran
或C++
函数;编写一个进行一些初步操作(如类型转换和类似操作)的包装器要好得多。如下所示:
test2Wrapp<-function(x) test2(as.numeric(x))
test2Wrapp(c())
#[1] 42
#This has the benefit to not calling the internal routines in cases where conversion isn't possible
test2Wrapp(iris)
#Error: (list) object cannot be coerced to type 'double'
test2Wrapp几个月前,我们添加了传递为Nullable
的功能,这可能正是您想要的
下面是一个简单的例子:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
bool checkNull(Nullable<NumericVector> x) {
if (x.isNotNull()) {
// do something
NumericVector xx(x);
Rcpp::Rcout << "Sum is " << sum(xx) << std::endl;
return true;
} else {
// do nothing
Rcpp::Rcout << "Nothing to see" << std::endl;
return false;
}
}
/*** R
checkNull(1:3)
checkNull(NULL)
*/
通过模板化,我们尊重预期的类型,但明确区分存在与否。请参见str(c())
。它不是一个数值向量numeric(0)
是一个长度为0的数值向量。@nicola解决了这个问题,谢谢!是否愿意作为答案发布?raw()
、logical()
、integer()
、double()
、complex()
和vector()
的输入也可以在这里使用。是的,这是由于特定的Rcpp
接口以及它接受的NumericVector
。显然,logical
、raw
和complex
都符合条件。我不想吹嘘太多,但它包含了他的答案,因为你还可以在幕后得到他推荐的所有健全检查。而且NULL
比长度0更明确。我接受了nicolas的答案,因为这是第一个答案,并回答了我的问题(在这个答案发布之前)。它提供了一个快速而简单的解决方法,对我来说效果很好,而这个答案展示了如何以更一般的方式在Rcpp中处理我的问题。作为Rcpp的新手,我从这两个答案中学到了很多,并且相信它们是互补的。请允许我删除之前的评论,以避免误解,再次感谢+1(我不是建议/要求你这样做,而是…)人们一直在交换接受的选票。SO的目的是让最好的解决方案产生泡沫。选择你认为对你的问题最好的回答。这就是绩效体系应该如何运作的。
R> sourceCpp("/tmp/null.cpp")
R> checkNull(1:3)
Sum is 6
[1] TRUE
R> checkNull(NULL)
Nothing to see
[1] FALSE
R>