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

Importing a csv file using fread loses factor order

当我尝试使用 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,3,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","Biology",..: 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 列声明为一个因素时,情况仍然存在。

问题 为什么 data.table 中的 fread(或 fwrite)函数不将主题列保留为 因素。当使用 colClasses 参数将 subject 列指定为一个因素时,为什么不保留 subject 列中级别的层次顺序?

正如@mt1022 所说:

This is expected behaviour, as you saved the factor column as character strings. When you read it again, fread or other data import functions have no idea of the original factor levels. If you want to preserve the attributes of the data, consider saving it as a .RDS file.