调用unlist
或c
时,类型将被提升为能够代表所有内容的最小类型:
> c(as.integer(1), 2.3, '3')
[1] "1" "2.3" "3"
> c(TRUE, 5)
[1] 1 5
> unlist(list(as.integer(1:5), as.complex(2:4)))
[1] 1+0i 2+0i 3+0i 4+0i 5+0i 2+0i 3+0i 4+0i
如何从C / C ++代码访问此逻辑?
我查找了c
和unlist
的C来源,并在do_c_dflt
和do_unlist
(main/bind.c
)中找到了以下代码:
if (data.ans_flags & 512) mode = EXPRSXP;
else if (data.ans_flags & 256) mode = VECSXP;
else if (data.ans_flags & 128) mode = STRSXP;
else if (data.ans_flags & 64) mode = CPLXSXP;
else if (data.ans_flags & 32) mode = REALSXP;
else if (data.ans_flags & 16) mode = INTSXP;
else if (data.ans_flags & 2) mode = LGLSXP;
else if (data.ans_flags & 1) mode = RAWSXP;
变量data
,类型为BindData
,由似乎定义强制逻辑的例程AnswerType
计算。但是,BindData
类型仅在bind.c
中声明。
那么:R的一般强制逻辑是否被导出到任何地方,或者我是否必须从bind.c
复制粘贴代码? (对不起,双关语......)
答案 0 :(得分:1)
凯文刚刚发布了an article on the Rcpp Gallery,其精神非常接近,它使用R的API显式测试:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List do_stuff( List x_ ) {
List x = clone(x_);
for( List::iterator it = x.begin(); it != x.end(); ++it ) {
switch( TYPEOF(*it) ) {
case REALSXP: {
NumericVector tmp = as<NumericVector>(*it);
tmp = tmp * 2;
break;
}
case INTSXP: {
if( Rf_isFactor(*it) ) break; // factors have type INTSXP too
IntegerVector tmp = as<IntegerVector>(*it);
tmp = tmp + 1;
break;
}
default: {
stop("incompatible SEXP encountered;");
}
}
}
return x;
}