使用sitecustomize.py
考虑这些示例来检查各种数据类型。为什么我检查Rcpp
会返回is_list
?
FALSE
答案 0 :(得分:2)
这可能是R.考虑这两个针对R API的普通C函数复制你的结果,但不涉及任何Rcpp:
R> library(inline)
R> f <- cfunction(signature(s="SEXP"), body="SEXP b = PROTECT(allocVector(INTSXP, 1)); INTEGER(b)[0] = Rf_isList(s); UNPROTECT(1); return b;")
R> f(list(a=1))
[1] 0
R> g <- cfunction(signature(s="SEXP"), body="SEXP b = PROTECT(allocVector(INTSXP, 1)); INTEGER(b)[0] = Rf_inherits(s, \"data.frame\"); UNPROTECT(1); return b;")
R> g(data.frame(a=1))
[1] 1
R>
所以实质上Rf_isList()
似乎错过了列表类型。背后可能有一个很好的理由,但我现在无法给它命名......
我们在src/include/Rinlinedfuns.h
INLINE_FUN Rboolean isList(SEXP s)
{
return (s == R_NilValue || TYPEOF(s) == LISTSXP);
}
这让我们很难看出这可能出错的地方。但也许你想戳到那里......
答案 1 :(得分:1)
请改用Rf_isNewList
。 (显然,列表的表示在某些时候发生了变化。)
这有效:
library(Rcpp)
cppFunction('bool is_list(SEXP data) {
return Rf_isNewList(data) ? true : false;
}')
is_list(list(a = 1))
#> TRUE
is_list(1)
#> FALSE
我认为做以下事情更为惯用:
cppFunction('bool is_list(SEXP data) {
return (TYPEOF(data) == VECSXP);
}')
这有一个好处,即NULL不是列表。