1

Rcpp の文字列処理に頭を悩ませているので、「Rcpp::CharacterVector 要素の等価性をテストする方法」を見てきましたが、状況はそれよりも少し複雑です。

説明のために、ランダムに生成された名前とマークの 200 行のデータ フレームがあるとします。

df = data.frame(name = paste("Person",
                             sample(LETTERS[1:10],200,rep=TRUE),sep=""), 
                mark = pmax(pmin(round(rnorm(200,60,15)),100),0), 
                stringsAsFactors=FALSE)

次のインライン コード (Rcpp を使用) は、名前が付けられた人物がデータ フレームで最初に指定された人物であるすべての行のマークの合計を正しく計算することがわかりました (つまり、R の df$name[1]、または同等の名前[0] Rcpp コード):

library(inline)

fastfunc_good1 <- cxxfunction(
    signature(DFin = "data.frame"),
    plugin = "Rcpp",
    body = '
        Rcpp::DataFrame DF(DFin);
        Rcpp::CharacterVector name = DF["name"];
        Rcpp::IntegerVector mark = DF["mark"];
        Rcpp::CharacterVector targetname(1);
        Rcpp::CharacterVector thisname(1);      

        int n = name.length();
        int tot = 0;
        targetname = name[0];
        std::string s_targetname = as<std::string>(targetname);

        for (int i = 0; i < n; i++) {
            thisname=name[i];
            std::string s_thisname = as<std::string>(thisname);
            if (s_thisname == s_targetname) {
                tot = tot + mark[i];
            }
        }

        return(Rcpp::wrap(tot));
        ')

name[] の値を表す別の変数を定義し、std::string に強制し、比較を行うのは面倒なので、これを可能な限り単純化したいと思います。次のように表記を単純化する何らかの方法が必要です (これは機能しないことに注意してください)...

fastfunc_bad1 <- cxxfunction(
    signature(DFin = "data.frame"),
    plugin = "Rcpp",
    body = '
        Rcpp::DataFrame DF(DFin);
        Rcpp::CharacterVector name = DF["name"];
        Rcpp::IntegerVector mark = DF["mark"];

        int n = name.length();
        int tot = 0;

        for (int i = 0; i < n; i++) {
            if (name[i] == name[0]) {
                tot = tot + mark[i];
            }
        }

        return(Rcpp::wrap(tot));
        ')

このミニ学習プロジェクトの最終的な目標は、df$name 内の一意の名前を反復処理し、それぞれのマークの合計を計算し、すべて (一意の名前と対応する合計) を適切なデータ フレームとして返す方法を理解することです。 . 私は、他の例から最終的なデータ フレームを構築して返す方法のほとんどの要点を理解しました。頭を悩ませているのは、上記の文字列だけです。ご指摘ありがとうございます。

4

1 に答える 1

5

Rcpp::as を使用して、R オブジェクトを C++ コンテナーに変換できます。以下は私にとってはうまくいきます。

fastfunc_good2 <- cxxfunction(
    signature(DFin = "data.frame"),
    plugin = "Rcpp",
    body = '
        Rcpp::DataFrame DF(DFin);
        std::vector<std::string> name = Rcpp::as<std::vector<std::string> >(DF["name"]);
        std::vector<int> mark = Rcpp::as<std::vector<int> >(DF["mark"]);

        int n = name.size();
        int tot = 0;

        for (int i = 0; i < n; i++) {
            if (name[i] == name[0]) {
                tot = tot + mark[i];
            }
        }

        return(Rcpp::wrap(tot));
        ')


> fastfunc_good1(df)
[1] 1040

> fastfunc_good2(df)
[1] 1040
于 2012-06-05T09:43:08.180 に答える