使用 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.
当我尝试使用 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.