2016-11-24 7 views
1

私はRのリストをループし、リストの各Rオブジェクトのプライマリクラス(S3クラスの場合は最初の要素として定義されています)を抽出しています。 RcppからジェネリックR関数を呼び出すことは可能ですが、これを避けたいと思います。私がこれを追求するのは、パフォーマンスのためです。Rのprimitive "class"関数にRcppでアクセスすることは可能ですか?

Rのプリミティブ関数へのアクセスに関して別の質問がありました。 use primitive functions in RcppとRcppの砂糖表現がその問題を解決したように見えますが、Rcppシュガーでは 'class'のようには見えません。

私は、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

はい - これはボトルネックの1つです。しかし、それがなかったとしても、私はまだメカニックに興味があります... – rlh2

答えて

2

内部でRが持つすべてのものがRcppで利用できるわけではありません。確かに自動メカニズムはありません(そのため、あなたが参照しているmax()の答えは異なるが、同等のmax()機能を示しています)。

しかし、あなた(S3をカバー)class属性を見ることができます。

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> 

同様に、あなたは他のオブジェクトの種類をテストし、ロジックを追加することができます。

関連する問題