9

Rcpp関数でデータ フレームを作成したいのですが、実際にデータ フレームのように見えません。ベクトルなどを押してみましたが、同じことになります。検討:

RcppExport SEXP makeDataFrame(SEXP in) {
    Rcpp::DataFrame dfin(in);
    Rcpp::DataFrame dfout;
    for (int i=0;i<dfin.length();i++) {
        dfout.push_back(dfin(i));
    }

    return dfout;
}

Rで:

> .Call("makeDataFrame",mtcars,"myPkg")
[[1]]
 [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
[16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
[31] 15.0 21.4

[[2]]
 [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4

[[3]]
 [1] 160.0 160.0 108.0 258.0 360.0 225.0 360.0 146.7 140.8 167.6 167.6 275.8
[13] 275.8 275.8 472.0 460.0 440.0  78.7  75.7  71.1 120.1 318.0 304.0 350.0
[25] 400.0  79.0 120.3  95.1 351.0 145.0 301.0 121.0

[[4]]
 [1] 110 110  93 110 175 105 245  62  95 123 123 180 180 180 205 215 230  66  52
[20]  65  97 150 150 245 175  66  91 113 264 175 335 109

[[5]]
 [1] 3.90 3.90 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 3.92 3.07 3.07 3.07 2.93
[16] 3.00 3.23 4.08 4.93 4.22 3.70 2.76 3.15 3.73 3.08 4.08 4.43 3.77 4.22 3.62
[31] 3.54 4.11

[[6]]
 [1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070
[13] 3.730 3.780 5.250 5.424 5.345 2.200 1.615 1.835 2.465 3.520 3.435 3.840
[25] 3.845 1.935 2.140 1.513 3.170 2.770 3.570 2.780

[[7]]
 [1] 16.46 17.02 18.61 19.44 17.02 20.22 15.84 20.00 22.90 18.30 18.90 17.40
[13] 17.60 18.00 17.98 17.82 17.42 19.47 18.52 19.90 20.01 16.87 17.30 15.41
[25] 17.05 18.90 16.70 16.90 14.50 15.50 14.60 18.60

[[8]]
 [1] 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 1 0 0 0 1

[[9]]
 [1] 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1

[[10]]
 [1] 4 4 4 3 3 3 3 4 4 4 4 3 3 3 3 3 3 4 4 4 3 3 3 3 3 4 5 5 5 5 5 4

[[11]]
 [1] 4 4 1 1 2 1 4 2 2 4 4 3 3 3 4 4 4 1 2 1 1 2 2 4 2 1 2 2 4 6 8 2
4

4 に答える 4

15

簡単に:

  • DataFrameは実際、共通の長さを持たなければならないという制限が追加されたリストと同じであるため、ごとに作成するのが最適です。

  • 最良の方法は、多くの場合、単体テストを探すことです。彼女はクラスinst/unitTests/runit.DataFrame.R のテストを再グループ化します。DataFrame

  • また、便利でSTLとの類似性のために追加したRcpp.push_back()のメンバー関数も見つかりました。推奨されないことを警告します。Rオブジェクトの構築方法が異なるため、基本的に常にフルコピーを実行する必要があるのはあまり効率的ではありません。.push_back

  • 私がここで頻繁に答えているにもかかわらず、rcpp-develリストはRcppの質問に適した場所です。

于 2011-12-25T22:15:55.940 に答える
9

名前を明示的に指定すれば、Rcppは適切なdata.frameを返すことができるようです。これを任意の名前の例に適応させる方法がわかりません

mkdf <- '
    Rcpp::DataFrame dfin(input);
    Rcpp::DataFrame dfout;
    for (int i=0;i<dfin.length();i++) {
        dfout.push_back(dfin(i));
    }

    return Rcpp::DataFrame::create( Named("x")= dfout(1), Named("y") = dfout(2));
'
library(inline)
test <- cxxfunction( signature(input="data.frame"),
                              mkdf, plugin="Rcpp")

test(input=head(iris))
于 2011-12-25T22:16:52.487 に答える
6

@baptiste's answerからの情報を使用して、これは最終的に整形式のデータ フレームを与えるものです。

RcppExport SEXP makeDataFrame(SEXP in) {
    Rcpp::DataFrame dfin(in);
    Rcpp::DataFrame dfout;
    Rcpp::CharacterVector namevec;
    std::string namestem = "Column Heading ";
    for (int i=0;i<2;i++) {
        dfout.push_back(dfin(i));
        namevec.push_back(namestem+std::string(1,(char)(((int)'a') + i)));
    }
    dfout.attr("names") = namevec;
    Rcpp::DataFrame x;
    Rcpp::Language call("as.data.frame",dfout);
    x = call.eval();
    return x;
}

push_back (@Dirk が示唆) と 2 番目の言語呼び出しの評価のために、これは非効率的である可能性があるという点は残っていると思います。私は rcpp unitTests を調べましたが、まだより良いものを思いつくことができませんでした. 誰にもアイデアはありますか?

アップデート:

@Dirkの提案を使用すると(ありがとう!)、これはよりシンプルで効率的なソリューションのようです:

RcppExport SEXP makeDataFrame(SEXP in) {
    Rcpp::DataFrame dfin(in);
    Rcpp::List myList(dfin.length());
    Rcpp::CharacterVector namevec;
    std::string namestem = "Column Heading ";
    for (int i=0;i<dfin.length();i++) {
        myList[i] = dfin(i); // adding vectors
        namevec.push_back(namestem+std::string(1,(char)(((int)'a') + i))); // making up column names
    }
    myList.attr("names") = namevec;
    Rcpp::DataFrame dfout(myList);
    return dfout;
}
于 2011-12-27T18:56:12.600 に答える
0

私はジョランに同意します。R 内から呼び出された C 関数の出力は、「in」と「out」の両方のすべての引数のリストであるため、データフレームの各「列」は、C 関数呼び出しで引数として表すことができます。C 関数呼び出しの結果が R にある場合は、リスト インデックスを使用してそれらのリスト要素を抽出し、適切な名前を付けるだけです。

于 2011-12-25T22:03:22.687 に答える