【问题标题】:Importing a csv file using fread loses factor order使用 fread 导入 csv 文件会丢失因子顺序
【发布时间】: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


【解决方案1】:

正如@mt1022 所说:

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

【讨论】:

  • 这是错误的。 read.csv 将按字母顺序排列因子水平。查看df$subjectdf2$subject 之间的输出差异。
  • 此外,由于 R 4.0.0,stringsAsFactors 参数的默认值为 FALSE;因此read.csv 应该给出字符列而不是因子列。
  • @Jaap 我的错,你是绝对正确的。我应该尽快解决这个问题
  • 我建议编辑答案,复制mt1022的评论,并转换为wiki答案。
  • @zx8754 我想我做到了
猜你喜欢
  • 1970-01-01
  • 2022-11-17
  • 2021-05-24
  • 2016-04-19
  • 2021-02-10
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 2021-08-02
相关资源
最近更新 更多