2016-04-14 3 views
-1

私のRcpp機能に問題があります。私は基本的にデータフレーム(次元N*K)と数値ベクトル(次元H < N)を入力として持ち、出力として整数ベクトルの同じ行インデックスを持つデータフレーム(寸法H * M)を返したいと思います。IDでRcppのdata.frameをサブセット化すると '要求の種類と互換性がありません'

データフレーム:

val1 val2 val3 val4 
1 0.2059 A 14 
2 0.5700 B 61 
3 0.5354 C 24 
4 0.8123 D 78 
5 0.7542 E 39 
6 0.6433 F 17 
7 0.2452 G 96 
8 0.2557 H 93 
9 0.7208 I 36 
10 0.2565 L 12 

整数ベクトル:

2 
4 
7 
10 

OUTPUT:

2 0.5700 B 61 
4 0.8123 D 78 
7 0.2452 G 96 
10 0.2565 L 12 

ここに私のコードです。あなたの助けを前もってありがとう:

#include <RcppArmadillo.h> 
using namespace Rcpp; 
// [[Rcpp::export]] 
DataFrame matchRows(DataFrame &OriginalDF, NumericVector &ReducedVector) 
{ 
    int nr1 = OriginalDF.nrows(), nc1= OriginalDF.size(); 
    int nr2 = ReducedVector.size(); 

    if (nr1 < nr2) throw std::range_error("Size of data frame has to be higher  than the target random subset!"); 

    std::map<double, DataFrame> X; 
    for (int j = 0; j < nr2; j++) 
    { 
    NumericVector tmp1=wrap(OriginalDF[ReducedVector[j]]); 
    tmp1.attr("dim")=Dimension(int(tmp1.size())/nc1,nc1); 

    DataFrame NewDF(wrap(tmp1)); 
    NewDF.push_back(OriginalDF[ReducedVector[j]]); 
    NewDF.attr("names")=OriginalDF.attr("names"); 

    X[ReducedVector[j]] = NewDF; 
    } 
    return wrap(X); 
} 

私の以前のバージョンのコードでは、残念ながらRStudioがクラッシュしました。理想的にはゼロにデータフレームを初期化してpush_back()を使用して値を追加するためのいくつかの方法があります:

// [[Rcpp::export]] 
DataFrame matchRows(DataFrame &OriginalDF, NumericVector &ReducedVector) 
{ 
    int nr1 = OriginalDF.nrows(), nc1 = OriginalDF.size(); 
    int nr2 = ReducedVector.size(); 

    if (nr1 < nr2) throw std::range_error("Size of data frame has to be higher than the target random subset!"); 

    DataFrame NewDF; 
    for (int j = 0; j < nr2; j++) 
    { 
    NewDF.push_back(OriginalDF[ReducedVector[j]]); 
    } 
    return NewDF; 
} 
+0

完全なエラーメッセージを入力して、コードのどの行でエラーが発生したかを示します。次に、デバッグを行います。つまり、すべての変数(特に代入または変換する変数)に期待する型があるかどうかを確認します。 – Roland

+0

Rcppスクリプトはエラーなしで実行されます。しかし、rで関数を呼び出すと、「要求タイプと互換性がありません」というエラーメッセージが表示されます。 –

+0

私はそれをexemple [here](http://stackoverflow.com/questions/24353078/rstudio-crashes-with-rcpp-with-reproducible-codes)にしたがってデバッグしようとしましたが、RStudioでも同じ問題が発生します。 –

答えて

2

わかりましたので、あなたが本当にちょうどRcppで行IDによってdata.frameをサブセットであり、ここでやろうとしているもの。

D[c(2,4,7,10),] 

まずアップ、あなたのコードでは以下を定義します。

std::map<double, DataFrame> X; 

このタイプのオブジェクトに対処するために何wrap()変換はありません。さらに、関数で指定された戻り値の型によって自動変換されるため、実際にはラップを使用しないでください。

.push_back()機能を使用しないでdata.frameを効率的にサブセット化するには、常にフルコピーが必要なため効率的ではありません。

代わりに、あなたはとても似idx変数とRcpp vector subsettingを使用したい:

#include <Rcpp.h> 

// Extract rows from data.frame object in Rcpp 
// [[Rcpp::export]] 
Rcpp::DataFrame matchRows(Rcpp::DataFrame D, Rcpp::IntegerVector idx) { 

    // First, break apart each vector 
    Rcpp::IntegerVector val1 = D["val1"]; 
    Rcpp::NumericVector val2 = D["val2"]; 
    Rcpp::CharacterVector val3 = D["val3"]; 
    Rcpp::NumericVector val4 = D["val4"]; 

    // We assume that the index passed in starts at 1. 
    // Hence, we need to adjust the idx to start at 0 with: 
    idx = idx - 1; 

    // Next up, create a new DataFrame Object with selected rows subset. 
    return Rcpp::DataFrame::create(Rcpp::Named("val1") = val1[idx], 
           Rcpp::Named("val2") = val2[idx], 
           Rcpp::Named("val3") = val3[idx], 
           Rcpp::Named("val3") = val4[idx] 
           ); 
} 

/*** R 
# Make some data 
set.seed(1337) 
D = data.frame(val1 = 1:10, 
       val2 = rnorm(10), 
       val3 = letters[1:10], 
       val4 = sample(1:100, 10), 
       stringsAsFactor=FALSE) 

# Create index that starts at 1 instead of 0. 
# This will be converted in the C++ function. 
idx = c(2,4,7,10) 

matchRows(D, idx) 

*/ 

は細部に悪魔たちはRの1の前に対0から始まるC++の指標を考慮するために1によってインデックスを減らすことですインデックスを呼び出します。これはC++コード内でも処理できます。しかし、私はそれを運動として残します。

+0

ありがとう、それは大丈夫です。数値行列のように、変数の名前を説明しないようにする別の方法があることを願っています。 –