R因子函数运行缓慢,数据帧较长

R因子函数运行缓慢,数据帧较长,r,performance,dataframe,categorical-data,dummy-variable,R,Performance,Dataframe,Categorical Data,Dummy Variable,我有一个很长的数据帧(数百万行,几列)。对于运行固定效应回归,我想使用factor函数将分类变量声明为因子,但这非常缓慢。我正在寻找一个可能的解决方案来加速它 我的代码如下: library(lfe) my_data=read.csv("path_to//data.csv") attach(data.frame(my_data)) 下面是非常慢的一行: my_data$col <- factor(my_data$col) my_data$col如果你知道你正在创建的因子的级别,这可以大

我有一个很长的数据帧(数百万行,几列)。对于运行固定效应回归,我想使用
factor
函数将分类变量声明为因子,但这非常缓慢。我正在寻找一个可能的解决方案来加速它

我的代码如下:

library(lfe)
my_data=read.csv("path_to//data.csv")
attach(data.frame(my_data))
下面是非常慢的一行:

my_data$col <- factor(my_data$col)

my_data$col如果你知道你正在创建的因子的级别,这可以大大加快速度。注意:

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 
还有一个由Kevin Ushley()编写的
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   
以下是修改后的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;
}
#包括
使用名称空间Rcpp;
模板
积分向量快速因子模板水平(常数向量和x,常数向量和水平){
IntegerVector out=匹配(x,levs);
out.attr(“levels”)=as(levs);
out.attr(“类”)=“因子”;
返回;
}
//[[Rcpp::导出]]
SEXP fast\u factor\u Levs(SEXP x,SEXP Levs){
开关(类型(x)){
案例INTSXP:返回快速系数模板(x,Levs);
case REALSXP:返回fast\u factor\u template\u Levs(x,Levs);
案例STRSXP:返回快速系数模板等级(x,等级);
}
返回R_值;
}

如果您知道所创建的因子的级别,这可以大大加快速度。注意:

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 
还有一个由Kevin Ushley()编写的
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   
以下是修改后的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;
}
#包括
使用名称空间Rcpp;
模板
积分向量快速因子模板水平(常数向量和x,常数向量和水平){
IntegerVector out=匹配(x,levs);
out.attr(“levels”)=as(levs);
out.attr(“类”)=“因子”;
返回;
}
//[[Rcpp::导出]]
SEXP fast\u factor\u Levs(SEXP x,SEXP Levs){
开关(类型(x)){
案例INTSXP:返回快速系数模板(x,Levs);
case REALSXP:返回fast\u factor\u template\u Levs(x,Levs);
案例STRSXP:返回快速系数模板等级(x,等级);
}
返回R_值;
}