如何避免在 fread 中将日期读取为 IDate

how to avoid reading dates as IDate in fread

这里问同样的问题没有解决,How to avoid fread() importing date info as IDate?

旧问题不是很具体,并且混合了其他一些问题,而且它不包含我在这里提出的代表。因此,我正在改进这个问题。请不要将其标记为重复:-)

问题是:每当我使用 data.table:: fread 读取包含日期列的 csv 文件时,它会将 Date 列的 class 更改为 IDate。如何避免这种情况并将其保留为日期格式?

library(data.table)
library(magrittr)
dt <- data.table(datecol = seq(Sys.Date(),by = "1 day",length.out = 3))
# let's confirm the format of the column is Date
str(dt)
#> Classes 'data.table' and 'data.frame':   3 obs. of  1 variable:
#>  $ datecol: Date, format: "2022-05-10" "2022-05-11" ...
#>  - attr(*, ".internal.selfref")=<externalptr>
# Now we write it into a file and read back using fwrite and fread
fwrite(dt,"tmpoutput.csv")
fread("tmpoutput.csv") %>% str
#> Classes 'data.table' and 'data.frame':   3 obs. of  1 variable:
#>  $ datecol: IDate, format: "2022-05-10" "2022-05-11" ...
#>  - attr(*, ".internal.selfref")=<externalptr>
# as you see the date format changes to IDate

reprex package (v2.0.1)

于 2022-05-10 创建

这不是一个大问题,但每次读取文件后都需要一行额外的代码,即 dt[,datecol:=as_date(datecol = as_date(datecol)] 这样具有类似 DT 的 rbind 就不会失败。

是否有更简单的方法来避免这种情况,因为如果我们稍后忘记进行类型转换,这可能是一个错误原因?

您可以创建一个新的 class(此处:importDate),并在 fread 的 colClasses 参数中引用它。这会强制将给定的列作为日期读入(而不是默认的 iDate)。

setClass("importDate")
# conversion
setAs("character", "importDate", function(from) as.Date(from))
# Now read, use a named vector in colClasses, so only identify the cols you explicitly want to convert to Date
fread("tmpoutput.csv", colClasses = c(datecol = "importDate")) %>% str
# Classes ‘data.table’ and 'data.frame':    3 obs. of  1 variable:
#   $ datecol: Date, format: "2022-05-10" "2022-05-11" "2022-05-12"
# - attr(*, ".internal.selfref")=<externalptr>

基于@Wimpel 的回答,您可以使用 colClasses 参数简单地指定列 类 :

fread("tmpoutput.csv",colClasses=c(datecol='Date')) %>% str

Classes ‘data.table’ and 'data.frame':  3 obs. of  1 variable:
 $ datecol: Date, format: "2022-05-10" "2022-05-11" "2022-05-12"
 - attr(*, ".internal.selfref")=<externalptr>