答:data.table。如何使用 fwrite 正确保存日期?
R: data.table. How to save dates properly with fwrite?
我有一个数据集。我可以选择从 Stata 文件或 SPSS 文件将其加载到 R 上。
在这两种情况下,它都正确加载了 haven 包。
日期被正确识别。
但是当我使用 data.table 的 fwrite 函数将它保存到磁盘时。
fwrite(ppp, "ppp.csv", sep=",", col.names = TRUE)
我有一个问题,日期消失并转换为不同的数字。例如,日期 1967-08-06 在 csv 文件中保存为 -879
我也试过使用 fwrite 选项,例如 quote=FALSE,但没有成功。
我上传了一小部分文件、spss、stata 和保存的 csv。
这是代码,是为了让您更轻松。
library(haven)
library(data.table)
ppp <- read_sav("pspss.sav") # choose one of these two.
ppp <- read_dta("pstata.dta") # choose one of these two.
fwrite(ppp, "ppp.csv", sep=",", col.names = TRUE)
真正的整体table有一千多个变量,一百万个人。这就是为什么我想用一种快速的方式来做事。
http://www73.zippyshare.com/v/OwzwbyQq/file.html
这是给@ArtificialBreeze 的:
> head(my)
# A tibble: 6 x 9
ID_2006_2011 TIS FECHA_NAC_2006 año2006 Edad_31_12_2006 SEXO_2006
<dbl> <chr> <date> <date> <dbl> <chr>
1 1.60701e+11 BBNR670806504015 1967-08-06 2006-12-31 39 M
2 1.60701e+11 BCBD580954916014 1958-09-14 2006-12-31 48 F
3 1.60701e+11 BCBL451245916015 1945-12-05 2006-12-31 61 F
4 1.60701e+11 BCGR610904916012 1961-09-04 2006-12-31 45 M
5 1.60701e+11 BCMR580148916015 1958-01-08 2006-12-31 48 F
6 1.60701e+11 BCMX530356917018 1953-03-16 2006-12-31 53 F
# ... with 3 more variables: PAIS_NAC_2006 <dbl>, FECHA_ALTA_TIS_2006 <date>,
# FECHA_ALTA_TIS_2006n <date>
由于似乎没有简单的解决方案,我正在尝试存储列 类 并再次将它们改回来。
我取原始数据集ppp,
areDates <- (sapply(ppp, class) == "Date")
我把它保存在一个文件里,下次可以看。
ppp <- fread("ppp.csv", encoding="UTF-8")
现在我将新读取的数据集的 类 改回原来的数据集。
ppp[,names(ppp)[areDates] := lapply(.SD,as.Date),
.SDcols = areDates ]
也许有人可以用 for 循环和命令集写得更好。
ppp[,lapply(.SD, setattr, "class", "Date") ,
.SDcols = areDates]
也可以写成位置而不是TRUE和FALSE的向量
我也遇到了同样的问题,只是写之前把日期栏改成as.character,读完又改回as.Date。我不知道它如何影响读写时间,但这对我来说是一个足够好的解决方案。
这些数字有意义 :) 似乎 fwrite 将数据格式更改为 "Matlab coding",其中来源为“1970-01-01”。
如果您阅读数据,您可以使用这些代码将数字简单地更改为日期:
my$FECHA_NAC_2006<-as.Date(as.numeric(my$FECHA_NAC_2006),origin="1970-01-01")
例如
as.Date(-879,origin="1970-01-01")
[1]“1967-08-06”
自从 6 个月前提出这个问题后,fwrite
已经改进并发布到 CRAN。我相信它现在应该可以正常工作了;即快速、直接和方便的日期格式。它现在有如下 dateTimeAs
参数,从 fwrite
's manual page 复制到 v1.10.0,就像现在在 CRAN 上一样。随着时间的推移,请查看最新版本的手册页。
====
dateTimeAs
: Date/IDate、ITime 和 POSIXct 项目的写入方式。
"ISO"(默认) - 2016-09-12
、18:12:16
和 2016-09-12T18:12:16.999999Z
。 0、3 或 6 位小数秒会在出现时为方便起见而打印,而不管任何 R 选项,例如 digits.secs。这个想法是,如果存在毫秒和微秒,那么您很可能希望保留它们。 R 的内部 UTC 表示被忠实地编写以鼓励 ISO 标准、阻止时区歧义和速度。要考虑的一个选项是在 shell 处简单地使用 "$ TZ='UTC' R" 在 UTC 时区启动 R(注意:TZ='UTC' 之间必须有一个或多个空格和 R,其他任何内容都将被默默忽略;此 TZ 设置仅适用于该 R 进程)或 Sys.setenv(TZ='UTC') 在 R 提示符下,然后继续,就好像 UTC 是本地时间一样。
"squash" - 20160912
、181216
和 20160912181216999
。此选项允许使用整数 div 和 mod 操作快速简单地提取 yyyy、mm、dd 和(最常见的分组依据)yyyymm 部分。例如,在 R 中,一行辅助函数可以分别使用 %/%10000、%/%100%%100、%%100 和 %/%100。 POSIXct UTC 被压缩为 17 位数字(始终包括 3 位毫秒数,即使是 000),可以舒适地读取为 integer64(由 fread() 自动读取)。
"epoch" - 17056
、65536
和 1473703936.999999
。自相关纪元(分别为 1970-01-01,00:00:00 和 1970-01-01T00:00:00Z)以来的基本天数或秒数,在此之前为负数(参见 ?Date)。如果存在,则打印 0、3 或 6 位小数秒。
"write.csv" - 这目前只影响 POSIXct。它被写成 write.csv 通过使用 as.character 方法来编写,该方法注意 digits.secs 并将 R 的内部 UTC 表示转换回本地时间(或 "tzone" 属性)历史日期。因此,这可能很慢。所有其他列类型(包括独立于时区的 Date、IDate 和 ITime)都使用已经与 write.csv.
[=52 一致的快速 C 代码编写为 "ISO" 选项=]
由于新的专用 C 代码,前三个选项速度很快。从 3 月 1 日开始,date-part 转换的纪元使用了 Howard Hinnant(请参阅参考资料)使用 day-of-year 的快速方法。您应该不会注意到这三个选项之间的写入速度有任何差异。 Date 和 IDate 支持的日期范围是 [0000-03-01, 9999-12-31]。这 3,652,365 个日期中的每一个都经过测试,并与基准 R 进行了比较,包括该范围内的所有 2,790 个闰日。此选项也适用于列表列单元格中 date/time 的向量。不支持完全灵活的格式字符串(例如“%m/%d/%Y”)。这是为了鼓励使用 ISO 标准,因为不知道如何在 C 级别上快速实现这种灵活性。如果需要,我们可能能够支持一两个更具体的选项。
====
您需要添加参数:dateTimeAs = "ISO"。
通过添加参数 dateTimeAs = 并指定适当的选项,您将在 csv 文件中获得具有所需格式和各自时区的日期。
这在处理与时区相关的 POSIXct 变量时尤为重要。缺少此参数可能会根据时区之间的小时差改变日期和时间,从而影响写入 csv 文件的时间戳。因此,date/time 变量 POSIXct,您需要添加: dateTimeAs = "write.csv" ;不幸的是,这个选项可能很慢 (https://www.rdocumentation.org/packages/data.table/versions/1.10.0/topics/fwrite?)。祝你好运!!!
我有一个数据集。我可以选择从 Stata 文件或 SPSS 文件将其加载到 R 上。
在这两种情况下,它都正确加载了 haven 包。
日期被正确识别。
但是当我使用 data.table 的 fwrite 函数将它保存到磁盘时。
fwrite(ppp, "ppp.csv", sep=",", col.names = TRUE)
我有一个问题,日期消失并转换为不同的数字。例如,日期 1967-08-06 在 csv 文件中保存为 -879
我也试过使用 fwrite 选项,例如 quote=FALSE,但没有成功。
我上传了一小部分文件、spss、stata 和保存的 csv。
这是代码,是为了让您更轻松。
library(haven)
library(data.table)
ppp <- read_sav("pspss.sav") # choose one of these two.
ppp <- read_dta("pstata.dta") # choose one of these two.
fwrite(ppp, "ppp.csv", sep=",", col.names = TRUE)
真正的整体table有一千多个变量,一百万个人。这就是为什么我想用一种快速的方式来做事。
http://www73.zippyshare.com/v/OwzwbyQq/file.html
这是给@ArtificialBreeze 的:
> head(my)
# A tibble: 6 x 9
ID_2006_2011 TIS FECHA_NAC_2006 año2006 Edad_31_12_2006 SEXO_2006
<dbl> <chr> <date> <date> <dbl> <chr>
1 1.60701e+11 BBNR670806504015 1967-08-06 2006-12-31 39 M
2 1.60701e+11 BCBD580954916014 1958-09-14 2006-12-31 48 F
3 1.60701e+11 BCBL451245916015 1945-12-05 2006-12-31 61 F
4 1.60701e+11 BCGR610904916012 1961-09-04 2006-12-31 45 M
5 1.60701e+11 BCMR580148916015 1958-01-08 2006-12-31 48 F
6 1.60701e+11 BCMX530356917018 1953-03-16 2006-12-31 53 F
# ... with 3 more variables: PAIS_NAC_2006 <dbl>, FECHA_ALTA_TIS_2006 <date>,
# FECHA_ALTA_TIS_2006n <date>
由于似乎没有简单的解决方案,我正在尝试存储列 类 并再次将它们改回来。
我取原始数据集ppp,
areDates <- (sapply(ppp, class) == "Date")
我把它保存在一个文件里,下次可以看。
ppp <- fread("ppp.csv", encoding="UTF-8")
现在我将新读取的数据集的 类 改回原来的数据集。
ppp[,names(ppp)[areDates] := lapply(.SD,as.Date),
.SDcols = areDates ]
也许有人可以用 for 循环和命令集写得更好。
ppp[,lapply(.SD, setattr, "class", "Date") ,
.SDcols = areDates]
也可以写成位置而不是TRUE和FALSE的向量
我也遇到了同样的问题,只是写之前把日期栏改成as.character,读完又改回as.Date。我不知道它如何影响读写时间,但这对我来说是一个足够好的解决方案。
这些数字有意义 :) 似乎 fwrite 将数据格式更改为 "Matlab coding",其中来源为“1970-01-01”。 如果您阅读数据,您可以使用这些代码将数字简单地更改为日期:
my$FECHA_NAC_2006<-as.Date(as.numeric(my$FECHA_NAC_2006),origin="1970-01-01")
例如
as.Date(-879,origin="1970-01-01")
[1]“1967-08-06”
自从 6 个月前提出这个问题后,fwrite
已经改进并发布到 CRAN。我相信它现在应该可以正常工作了;即快速、直接和方便的日期格式。它现在有如下 dateTimeAs
参数,从 fwrite
's manual page 复制到 v1.10.0,就像现在在 CRAN 上一样。随着时间的推移,请查看最新版本的手册页。
====
dateTimeAs
: Date/IDate、ITime 和 POSIXct 项目的写入方式。
"ISO"(默认) -
2016-09-12
、18:12:16
和2016-09-12T18:12:16.999999Z
。 0、3 或 6 位小数秒会在出现时为方便起见而打印,而不管任何 R 选项,例如 digits.secs。这个想法是,如果存在毫秒和微秒,那么您很可能希望保留它们。 R 的内部 UTC 表示被忠实地编写以鼓励 ISO 标准、阻止时区歧义和速度。要考虑的一个选项是在 shell 处简单地使用 "$ TZ='UTC' R" 在 UTC 时区启动 R(注意:TZ='UTC' 之间必须有一个或多个空格和 R,其他任何内容都将被默默忽略;此 TZ 设置仅适用于该 R 进程)或 Sys.setenv(TZ='UTC') 在 R 提示符下,然后继续,就好像 UTC 是本地时间一样。"squash" -
20160912
、181216
和20160912181216999
。此选项允许使用整数 div 和 mod 操作快速简单地提取 yyyy、mm、dd 和(最常见的分组依据)yyyymm 部分。例如,在 R 中,一行辅助函数可以分别使用 %/%10000、%/%100%%100、%%100 和 %/%100。 POSIXct UTC 被压缩为 17 位数字(始终包括 3 位毫秒数,即使是 000),可以舒适地读取为 integer64(由 fread() 自动读取)。"epoch" -
17056
、65536
和1473703936.999999
。自相关纪元(分别为 1970-01-01,00:00:00 和 1970-01-01T00:00:00Z)以来的基本天数或秒数,在此之前为负数(参见 ?Date)。如果存在,则打印 0、3 或 6 位小数秒。"write.csv" - 这目前只影响 POSIXct。它被写成 write.csv 通过使用 as.character 方法来编写,该方法注意 digits.secs 并将 R 的内部 UTC 表示转换回本地时间(或 "tzone" 属性)历史日期。因此,这可能很慢。所有其他列类型(包括独立于时区的 Date、IDate 和 ITime)都使用已经与 write.csv.
[=52 一致的快速 C 代码编写为 "ISO" 选项=]
由于新的专用 C 代码,前三个选项速度很快。从 3 月 1 日开始,date-part 转换的纪元使用了 Howard Hinnant(请参阅参考资料)使用 day-of-year 的快速方法。您应该不会注意到这三个选项之间的写入速度有任何差异。 Date 和 IDate 支持的日期范围是 [0000-03-01, 9999-12-31]。这 3,652,365 个日期中的每一个都经过测试,并与基准 R 进行了比较,包括该范围内的所有 2,790 个闰日。此选项也适用于列表列单元格中 date/time 的向量。不支持完全灵活的格式字符串(例如“%m/%d/%Y”)。这是为了鼓励使用 ISO 标准,因为不知道如何在 C 级别上快速实现这种灵活性。如果需要,我们可能能够支持一两个更具体的选项。
====
您需要添加参数:dateTimeAs = "ISO"。 通过添加参数 dateTimeAs = 并指定适当的选项,您将在 csv 文件中获得具有所需格式和各自时区的日期。 这在处理与时区相关的 POSIXct 变量时尤为重要。缺少此参数可能会根据时区之间的小时差改变日期和时间,从而影响写入 csv 文件的时间戳。因此,date/time 变量 POSIXct,您需要添加: dateTimeAs = "write.csv" ;不幸的是,这个选项可能很慢 (https://www.rdocumentation.org/packages/data.table/versions/1.10.0/topics/fwrite?)。祝你好运!!!