使用Rcpp检查列表失败

时间:2017-11-29 21:56:35

标签: r rcpp

使用sitecustomize.py考虑这些示例来检查各种数据类型。为什么我检查Rcpp会返回is_list

FALSE

参考

2 个答案:

答案 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不是列表。