【发布时间】:2021-01-16 21:27:33
【问题描述】:
当我尝试使用 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 列中的级别的层次顺序没有保留?
【问题讨论】:
-
这是预期行为,因为您将因子列保存为字符串。再次阅读时,
fread或其他数据导入功能不知道原始因子水平。如果要保留数据的属性,请考虑将其保存为 .RDS 文件。 -
或者使用 csvy,一个带有 yaml 元数据头的 csv
标签: r data.table fwrite fread