2017-04-06 7 views
1

長いデータフレーム(数百万行、数列)があります。固定効果回帰を実行するには、factor関数を使用してカテゴリ変数を要因として宣言したいが、これは非常に遅い。私はそれをスピードアップするための潜在的な解決策を探しています。次のようにRファクタ機能が長いデータフレームで遅く実行中

私のコードは次のとおりです。あなたが作成している要因のレベルを知っている場合、これは高速化することができます

my_data$col <- factor(my_data$col) 

答えて

3

library(lfe) 
my_data=read.csv("path_to//data.csv") 
attach(data.frame(my_data)) 

と次は非常に遅いラインでありますかなり物事観察:

library(microbenchmark) 
set.seed(237) 
test <- sample(letters, 10^7, replace = TRUE) 
microbenchmark(noLevels = factor(test), withLevels = factor(test, levels = letters), times = 20) 
Unit: milliseconds 
     expr  min  lq  mean median  uq  max neval cld 
    noLevels 523.6078 545.3156 653.4833 696.4768 715.9026 862.2155 20 b 
withLevels 248.6904 270.3233 325.0762 291.6915 345.7774 534.2473 20 a 

OPの状況のレベルを取得するには、単にuniqueを呼び出します。

myLevels <- unique(my_data$col) 
my_data$col <- factor(my_data$col, levels = myLevels) 

ケビンUshley(Fast factor generation with Rcpp)によって書かれたRcpp製品もあります。私は、レベルを知っているだろうと仮定して少しだけコードを修正しました先験的。参照されるウェブサイトからの機能はRcppNoLevsであり、修正されたRcpp関数はRcppWithLevsであり、以下のベンチマークである。ここ

microbenchmark(noLevels = factor(test), 
       withLevels = factor(test, levels = letters), 
       RcppNoLevs = fast_factor(test), 
       RcppWithLevs = fast_factor_Levs(test, letters), times = 20) 
Unit: milliseconds 
     expr  min  lq  mean median  uq  max neval cld 
    noLevels 571.5482 609.6640 672.1249 645.4434 704.4402 1032.7595 20 d 
    withLevels 275.0570 294.5768 318.7556 309.2982 342.8374 383.8741 20 c 
    RcppNoLevs 189.5656 203.3362 213.2624 206.9281 215.6863 292.8997 20 b 
RcppWithLevs 105.7902 111.8863 120.0000 117.9411 122.8043 173.8130 20 a 

は、1つの引数としてレベルを通過する前提修飾Rcpp関数である:

#include <Rcpp.h> 
using namespace Rcpp; 

template <int RTYPE> 
IntegerVector fast_factor_template_Levs(const Vector<RTYPE>& x, const Vector<RTYPE>& levs) { 
    IntegerVector out = match(x, levs); 
    out.attr("levels") = as<CharacterVector>(levs); 
    out.attr("class") = "factor"; 
    return out; 
} 

// [[Rcpp::export]] 
SEXP fast_factor_Levs(SEXP x, SEXP levs) { 
    switch(TYPEOF(x)) { 
    case INTSXP: return fast_factor_template_Levs<INTSXP>(x, levs); 
    case REALSXP: return fast_factor_template_Levs<REALSXP>(x, levs); 
    case STRSXP: return fast_factor_template_Levs<STRSXP>(x, levs); 
    } 
    return R_NilValue; 
} 
関連する問題