2016-11-24 164 views
1

我正在尝试通过R列表循环,并提取列表中每个R对象的主类(在S3类的情况下定义为第一个元素)。我知道可以从Rcpp调用一个通用的R函数,但我想避免这样做。我开始追求这个目标的原因是因为表演。是否可以通过Rcpp访问R的原始“类”功能?

我在这里看到关于访问R的原始函数的另一个问题: use primitive functions in Rcpp它看起来像Rcpp的糖表达式解决了这个特殊问题,但它看起来不像'class'在Rcpp糖中可用。我知道可以访问Rcpp中的属性(这是S3类的存储方式),我也知道S4对象在Rcpp中是可检测的,所以我认为可能有一种方法可以做到这一点,但它会是最简单的原始类函数可以直接调用,我只是缺少一些东西。

library(Rcpp) 

objList <- list(
    a = 10, 
    b = lm(mpg~cyl, data = mtcars), 
    c = glm(mpg~cyl, data = mtcars, family = gaussian) 
) 
##R approach 
primaryClass <- function(x){ 
    class(x)[1] 
} 

vapply(objList, primaryClass, character(1)) 

##Rcpp skeleton approach 
cppFunction('CharacterVector primaryClass(List x) { 
    int nrow = x.size(); 
    CharacterVector out(nrow); 
    for (int i = 0; i < nrow; i++) { 
    out[i] = "classHere"; 
    } 
    return out; 
}') 

primaryClass(objList) 
+1

你是否分析了你的代码?你确定这是瓶颈吗? –

+0

是的 - 这是瓶颈之一。不过,即使不是,我仍然对机制感兴趣...... – rlh2

回答

2

并非R“内部”具有的所有内容都可供Rcpp使用。肯定没有自动机制(这就是为什么您参考的max()上的答案显示不同但等效的max()函数)。

但是你可以class属性(其覆盖S3):

R> cppFunction('std::string getClass(RObject x) { 
+  if (x.hasAttribute("class")) return x.attr("class"); else return ""; }') 
R> getClass(lm.D9)   # after running `example(lm)` to get `lm.D9` 
[1] "lm" 
R> getClass(2.345) 
[1] "" 
R> 

同样可以测试的其他对象类型和添加逻辑。

相关问题