使用fread丢失因子顺序导入CSV文件

问题描述

当我尝试使用data.table函数fread读取以前保存的CSV文件时,不会保留我的数据的分类顺序。它按字母顺序格式化。

为复制此问题,我使用data.table

创建了一个伪数据集
dat <- data.table(name = c("Joe","Bob","Steve","Lucy","Eric","Marshall","Henry"),subject  = as.factor(c(4,1,2,3,4,2)))

然后使用setattr函数标记名为subject的因子列的级别。

setattr(dat$subject,"levels",c("Math","Biology","Sport","ICT"))

这就是数据集的样子。

       name subject
1:      Joe     ICT
2:      Bob    Math
3:    Steve Biology
4:     Lucy   Sport
5:     Eric     ICT
6: Marshall   Sport
7:    Henry Biology

我检查数据集的结构以及主题因素内级别的顺序。 subject列是因子,水平与我设置的顺序完全相同。

str(dat) 

   Classes ‘data.table’ and 'data.frame':   7 obs. of  2 variables:
 $ name   : chr  "Joe" "Bob" "Steve" "Lucy" ...
 $ subject: Factor w/ 4 levels "Math",..: 4 1 2 3 4 3 2
 - attr(*,".internal.selfref")=<externalptr> 

as.ordered(dat$subject)

Levels: Math < Biology < Sport < ICT

当我使用fwrite保存数据集,然后使用fread打开数据集时,subject列变成一个字符,并且级别按字母顺序排列。

# save the data
fwrite(dat,file = "dat.csv",sep = "\t")

# read data
dat2 <- fread("dat.csv")

# check structure 
str(dat2)

Classes ‘data.table’ and 'data.frame':  7 obs. of  2 variables:
 $ name   : chr  "Joe" "Bob" "Steve" "Lucy" ...
 $ subject: chr  "ICT" "Math" "Biology" "Sport" ...
 - attr(*,".internal.selfref")=<externalptr> 

# check order of the levels in subject
as.ordered(dat2$subject)

Levels: Biology < ICT < Math < Sport

当我使用colClasses参数并声明subject列作为因素时,情况仍然存在。

问题 为什么fread中的fwrite(或data.table函数没有将主题列保留为因素。并且当使用colClasses参数将subject列指定为因素而受到控制时,为什么subject列中的级别的层次结构顺序没有保留?

解决方法

正如@ mt1022所说:

这是预期的行为,因为您将因子列保存为字符串。当您再次阅读它时,读取或其他数据导入功能将不了解原始因子水平。如果要保留数据的属性,请考虑将其另存为.RDS文件。