2016-06-12 58 views
-2

給定一個包含多個列的data.frame,使用rcpp而不是R來計算列中值的組合的最快方法是確保更好的性能?使用rcpp對數據幀中的組合數進行計數

例如,考慮下面的data.frame稱爲DF,以列A,B,C,d,E

 A B C D E 
    1 1 1 1 1 2 
    2 1 1 1 1 2 
    3 2 2 2 2 3 
    4 2 2 2 2 3 
    5 3 3 3 3 1 

預期輸出如下:

 A B C D E count 
    1 1 1 1 1 2 2 
    2 2 2 2 2 3 2 
    3 3 3 3 3 1 1 

在R,可以通過創建一個結合現有列的新列並使用表來查找計數來完成,即:

df$combine <- do.call(paste, c(df, sep = "-")) 
tab <- as.data.frame(table(df$combine)) 

Becau在R中數據按摩和表格命令的性能有點慢,有沒有人知道和快速在Rcpp中做同樣的事情?

+0

[這](http://stackoverflow.com/questions/18201074/find-how-many-times -duplicated-rows-repeat-in-r-data-frame)答案可能會有所幫助。 –

回答

0

好的,這是我能想到的一種方法。

首先,我們真的不能在Rcpp中使用Rcpp::DataFrame對象類型,因爲它確實是一個鬆散的向量列表。所以,我通過創建與採樣數據相匹配的Rcpp::NumericMatrix來降低此問題的閾值。從這裏開始,可以使用std::map來計算唯一的行數。這是簡化的,因爲Rcpp::NumericMatrix具有啓用子集的.row()屬性。所以,每一行然後被轉換爲一個std::vector<T>,它被用作地圖的關鍵字。然後,我們將每個std::vector<T>添加到std::map並增加其計數值。最後,我們將std::map導出爲所需的矩陣格式。

#include <Rcpp.h> 

// [[Rcpp::export]] 
Rcpp::NumericMatrix unique_rows(Rcpp::NumericMatrix & v) 
{ 

    // Initialize a map 
    std::map<std::vector<double>, int> count_rows; 

    // Clear map 
    count_rows.clear(); 

    // Count each element 
    for (int i = 0; i != v.nrow(); ++i) { 
    // Pop from R Matrix 
    Rcpp::NumericVector a = v.row(i); 
    // Convert R vector to STD vector 
    std::vector<double> b = Rcpp::as< std::vector<double> >(a); 

    // Add to map 
    count_rows[ b ] += 1; 
    } 

    // Make output matrix 
    Rcpp::NumericMatrix o(count_rows.size(), v.ncol()+1); 

    // Hold count iteration 
    unsigned int count = 0; 

    // Start at the 1st element and move to the last element in the map. 
    for(std::map<std::vector<double>,int>::iterator it = count_rows.begin(); 
     it != count_rows.end(); ++it) 
    { 

    // Grab the key of the matrix 
    std::vector<double> temp_o = it->first; 

    // Tack on the vector, probably can be speed up. 
    temp_o.push_back(it->second); 

    // Convert from std::vector to Rcpp::NumericVector 
    Rcpp::NumericVector mm = Rcpp::wrap(temp_o); 

    // Store in a NumericMatrix 
    o.row(count) = mm; 

    count++; 
    } 

    return o; 
} 

然後我們一起去:

a = matrix(c(1, 1, 1, 1, 2, 
1, 1, 1, 1, 2, 
2, 2, 2, 2, 3, 
2, 2, 2, 2, 3, 
3, 3, 3, 3, 1), ncol = 5, byrow = T) 


unique_rows(a) 

,並提供:

 [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 1 1 1 2 2 
[2,] 2 2 2 2 3 2 
[3,] 3 3 3 3 1 1 
+0

我得到的感覺,相當模糊地給我的水平,unique_rows < - function(x){require(rcpp)然後你的代碼如上面的結果給予:但是對於我們這些試圖在家裏進行轉換的人... – Chris

+0

@nrussell你有更好的方法去做這件事嗎? – coatless

+0

@Chris,我不確定你是否是一個巨魔賬戶,或者這是一個嚴重的問題。如果是後者,請參閱:['Rcpp :: sourceCpp()'](http://www.inside-r.org/packages/cran/rcpp/docs/sourceCpp) – coatless