data.table :: fread的stringsAsFactors = TRUE参数不会将字符列转换为因子类型 - 解决方法是什么?

时间:2015-07-10 21:01:59

标签: r string dataframe data.table categorical-data

我知道这个问题已经在几个地方提出过,我一直试图找出一个可能很好的解决方案几个小时但是失败了。这就是我问这个的原因。

所以,我有一个巨大的数据文件(~5GB),我使用fread()来阅读这个

library(data.table)
df<- fread('output.txt', sep = "|", stringsAsFactors = TRUE)
head(df, 5)
       age            income homeowner_status_desc marital_status_cd gender
1:         $35,000 - $49,999                                               
2: 35 - 44 $35,000 - $49,999                  Rent            Single      F
3:         $35,000 - $49,999                                               
4:                                                                         
5:         $50,000 - $74,999 
str(df)
Classes ‘data.table’ and 'data.frame':  999 obs. of  5 variables:
 $ age                  : chr  "" "35 - 44" "" "" ...
 $ income               : chr  "$35,000 - $49,999" "$35,000 - $49,999" "$35,000 - $49,999" "" ...
 $ homeowner_status_desc: chr  "" "Rent" "" "" ...
 $ marital_status_cd    : chr  "" "Single" "" "" ...
 $ gender               : chr  "" "F" "" "" ...
 - attr(*, ".internal.selfref")=<externalptr> 

缺少数据(它是空白的)。在原始数据中,有很多列,因此我需要找到一种方法,只要列包含字符串就可以生成列。有谁能建议完成这项工作的最佳做​​法是什么?我正在考虑将其更改为数据框并执行此操作。但是,当它是data.table时,是否可以这样做?

4 个答案:

答案 0 :(得分:9)

在v 1.9.6 +

中为stringsAsFactors实施了fread参数

来自NEWS

  
      
  1. stringsAsFactors实施fread()参数。当TRUE时,字符列将转换为因子。默认值为FALSE。感谢Artem Klevtsov提交#501,以及@ hmi2015提交this SO post
  2.   

答案 1 :(得分:0)

这基本上是一个评论,但它很长,所以这里。

您可能希望使用colClasses来指定哪些列是因素。

如果你有很多专栏,我为简化做的事情是使用我写的以下函数:

abbr_to_colClass<-function(inits,counts){
  x<-substring(inits,1:nchar(inits),1:nchar(inits))
  types<-ifelse(x=="c","character",
                ifelse(x=="f","factor",
                       ifelse(x=="i","integer",
                              "numeric")))
  rep(types,substring(counts,1:nchar(counts),1:nchar(counts)))
}

假设你有一个.csv列的课程:

character 3
factor    2
integer   1
numeric   5
character 6

然后你可以用我的功能来设置

colClasses=abbr_to_colClass("cfinc","32156")

如果您连续使用一种类型的长字符串,这将特别节省空间。

(我知道这不是最强大的功能,但是当有很多字段需要阅读时,它很好地服务了我很多次)

答案 2 :(得分:0)

我制作了一个小csv文件,我可以确认其中stringsAsFactors = TRUE不会导致因子列的相同行为。另外,将colClasses指定为因子似乎也不起作用。

如果您在fread后运行此操作,则会将所有字符列转换为因子

for (j in which(sapply(df, class)=='character')) set(df, i=NULL, j=j, value=as.factor(df[[j]]))

答案 3 :(得分:0)

尝试使用新的readr软件包,它已经过优化,速度提高了10倍,而且没有内存泄漏。您现在可以指定col_types参数,而不是stringsAsFactors,您可以在其中指定collector(自定义解析器函数)。看看文档,尤其是col_factor/parse_factor

require(readr)
read_csv(..., col_types=...)