问题描述
当我尝试使用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文件。