2016-11-19 36 views
-1

的RCPP子集行我希望在Rcpp打造iris數據集的這樣的一個子集:數據框中

head(subset(iris, Species == "versicolor")) 

    Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
51   7.0   3.2   4.7   1.4 versicolor 
52   6.4   3.2   4.5   1.5 versicolor 
53   6.9   3.1   4.9   1.5 versicolor 
54   5.5   2.3   4.0   1.3 versicolor 
55   6.5   2.8   4.6   1.5 versicolor 
56   5.7   2.8   4.5   1.3 versicolor 

我知道如何子集Rcpp::DataFrame列 - 有重載運算符[其工作方式在R: x["var"]。但是,我找不到任何方法可以讓我將DataFrame的行分成不固定數量的列。

我想寫一個函數subset_rows_rcpp_iris需要Rcpp::DataFrame(它將永遠是光圈)和CharacterVector level_of_species作爲輸入。它會返回DataFrame對象。

DataFrame subset_rows_rcpp_iris(DataFrame x, CharacterVector level_of_species) { 
    ... 
} 

首先,我想找到滿足邏輯查詢的行的索引。我的問題是,如果我在test功能訪問Species載體,將其保存爲CharacterVector,然後將其與level_of_species比較,我得到永遠只有一個TRUE值的setosa情況下,在其他情況下,FALSE值。

cppFunction(' 
    LogicalVector test(DataFrame x, CharacterVector level_of_species) { 
      CharacterVector sub = x["Species"]; 
      LogicalVector ind = sub == level_of_species; 
      return(ind); 
      } 
') 
head(test(iris, "setosa")) 

[1] TRUE FALSE FALSE FALSE FALSE FALSE 

如果這個工作,我可以重寫test功能,並使用與載體TRUE/FALSE的值單獨子集中的每個數據幀的柱中,然後用Rcpp::DataFrame::create再次將它們結合起來。

+0

是的的確的。但是,我不知道如何在C++中表示字符標量。在Rcpp中沒有像'CharacterScalar'這樣的類。 '字符串'也不起作用。 –

+1

對吧!我的錯誤..因爲有NumericScalar我想同樣在這裏....我認爲我們假設R在C++ recylcing在這裏做sub == level_of_species –

+0

我們需要一個for循環 –

回答

1
cppFunction('LogicalVector test(DataFrame x, StringVector level_of_species) { 
    using namespace std; 
    StringVector sub = x["Species"]; 
    std::string level = Rcpp::as<std::string>(level_of_species[0]); 
    Rcpp::LogicalVector ind(sub.size()); 
    for (int i = 0; i < sub.size(); i++){ 
     ind[i] = (sub[i] == level); 
    } 

    return(ind); 
}') 

xx=test(iris, "setosa") 
> table(xx) 
xx 
FALSE TRUE 
    100 50 

子集進行! (我自己從這個問題學到了很多..謝謝!)

cppFunction('Rcpp::DataFrame test(DataFrame x, StringVector level_of_species) { 
    using namespace std; 
    StringVector sub = x["Species"]; 
    std::string level = Rcpp::as<std::string>(level_of_species[0]); 
    Rcpp::LogicalVector ind(sub.size()); 
    for (int i = 0; i < sub.size(); i++){ 
    ind[i] = (sub[i] == level); 
    } 

// extracting each column into a vector 
Rcpp::NumericVector SepalLength = x["Sepal.Length"]; 
Rcpp::NumericVector SepalWidth = x["Sepal.Width"]; 
Rcpp::NumericVector PetalLength = x["Petal.Length"]; 
Rcpp::NumericVector PetalWidth = x["Petal.Width"]; 


return Rcpp::DataFrame::create(Rcpp::Named("Sepal.Length") = SepalLength[ind], 
           Rcpp::Named("Sepal.Width") = SepalWidth[ind], 
           Rcpp::Named("Petal.Length") = PetalLength[ind], 
           Rcpp::Named("Petal.Width") = PetalWidth[ind] 
);}') 

yy=test(iris, "setosa") 
> str(yy) 
'data.frame': 50 obs. of 4 variables: 
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... 
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... 
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... 
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...