如何将此日期格式转换为 lubridate 接受的格式?
How can I convert this date-format in a format accepted by lubridate?
我已经从 Excel sheet 包 readxl.
中导入数据到 R
sheet 包含带有日期的列。这些日期的行为类似于 Excel 中的日期(我可以更改 Excel 中的日期格式)。
直接在R中用readxl导入后格式是这样的:
# A tibble: 1 x 1
`datum`
<dttm>
1 2010-01-20 21:00:00
我的目标是对导入的日期使用 lubridate 函数 days_in_month。
lubridate::days_in_month(df[2,1])
尽管使用此函数会出现此错误:
Error in as.POSIXlt.default(x, tz = tz(x)) :
do not know how to convert 'x' to class “POSIXlt”
我做了几个测试来识别格式:
is.Date(df[2,1])
is.POSIXt(df[2,1])
is.instant(df[2,1])
全部给出结果 FALSE。
如果我打印一个日期,我会收到这样的结果:
# A tibble: 1 x 1
`datum`
<dttm>
1 2010-01-20 21:00:00
我试过几次转换:
df$datum <- as.Date(df$datum, origin = "1899-12-30")
df$datum <- as.Date(as.POSIXct(df$datum, 'GMT'))
df$datum <- as.Date(df$datum, format='%Y-%m-%d')
虽然转换后上面的测试结果都是FALSE
如果我进行第一次转换 as.Date(df$datum, origin = "1899-12-30")。
在此之后打印的结果是:
# A tibble: 1 x 1
`datum`
<date>
1 2010-01-20
df$datum + 60 gives:
1 2010-03-21
所以它看起来像是一个日期,因为我可以添加 60。
尽管所有测试都给出 FALSE 并且来自 lubridate 的 days_in_month 仍然给出上述错误。
如何将日期转换为 lubridate 可以处理的正确格式?
非常感谢!
您被 data.frame
和 tbl_df
之间的 [
差异所困扰。阅读您的文件(出现在评论中),我最终看到:
df <- readxl::read_excel("example dates.xlsx")
df
# # A tibble: 3 x 2
# datum datum2
# <dttm> <dttm>
# 1 2010-01-01 13:25:00 2010-12-22 23:53:40
# 2 2010-01-23 13:30:00 2011-01-07 23:09:10
# 3 2010-02-16 21:45:00 2011-03-19 01:00:52
# for everybody else
df <- structure(list(datum = structure(c(1262352300, 1264253400, 1266356700), class = c("POSIXct", "POSIXt"), tzone = "UTC"), datum2 = structure(c(1293062020.704, 1294441750.08, 1300496452.128), class = c("POSIXct", "POSIXt"), tzone = "UTC")), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
我们能否同意尝试一次转换整个帧没有意义?
as.Date(df)
# Error in as.Date.default(df) :
# do not know how to convert 'df' to class "Date"
愚蠢的问题。好吧,让我们看看其他变体会发生什么。
df$datum
# [1] "2010-01-01 13:25:00 UTC" "2010-01-23 13:30:00 UTC" "2010-02-16 21:45:00 UTC"
as.Date(df$datum)
# [1] "2010-01-01" "2010-01-23" "2010-02-16"
df[2,1]
# # A tibble: 1 x 1
# datum
# <dttm>
# 1 2010-01-23 13:30:00
as.Date(df[2,1])
# Error in as.Date.default(df[2, 1]) :
# do not know how to convert 'df[2, 1]' to class "Date"
使用简单的 data.frame
,[2,1]
将 return 一个标量,而不是一个框架,因此这在基数 R 中是有意义的:
as.data.frame(df)[2,1]
# [1] "2010-01-23 13:30:00 UTC"
as.Date(as.data.frame(df)[2,1])
# [1] "2010-01-23"
所以问题是 tibble
迫使你明确表示你想从一个框架下降到 scalar/vector.
坦率地说,这通常是一件好事。在处理 "normal"(非 tibble
)帧并且您想查看一组列时,as.data.frame(df[,1:2])
,R 总是 return 是 data.frame
。不幸的是,如果您以编程方式定义列并且它 return 是单个列,那么 [
默认情况下会将它从一个帧减少到一个向量:as.data.frame(df)[,1]
。您可以使用 drop=
、ala as.data.frame(df[,1,drop=FALSE])
来防止这种自动强制转换。许多人(包括我自己)认为这是一个错误:df[,cols]
应该依赖于始终 return 相同类型的对象,无论它是 20 列还是只有 1 列。 (我知道它这样做是有原因的,我并不是在责备最初的 R 开发人员。)
因此导致您出错的 问题 是 tibble
要求您在将 tbl_df
子集化为单个单元格时明确说明。如果您想在单个单元格上工作,请使用 df$datum[2]
或 df[2,1][[1]]
强制它。如果您想处理整个专栏,那么 df$datum
。所有这些都直接与 as.Date
一起工作,因为它知道如何处理 POSIXt
(本机)和 numeric
/integer
(以及 origin=
的向量).不幸的是,df[,1]
的 tibble 不会 return 向量,因此 as.Date
不知道如何处理它。
底线:
as.Date(df$datum[2])
# [1] "2010-01-23"
as.Date(df[2,1][[1]])
# [1] "2010-01-23"
as.Date(df$datum)
# [1] "2010-01-01" "2010-01-23" "2010-02-16"
我已经从 Excel sheet 包 readxl.
中导入数据到 Rsheet 包含带有日期的列。这些日期的行为类似于 Excel 中的日期(我可以更改 Excel 中的日期格式)。
直接在R中用readxl导入后格式是这样的:
# A tibble: 1 x 1
`datum`
<dttm>
1 2010-01-20 21:00:00
我的目标是对导入的日期使用 lubridate 函数 days_in_month。
lubridate::days_in_month(df[2,1])
尽管使用此函数会出现此错误:
Error in as.POSIXlt.default(x, tz = tz(x)) :
do not know how to convert 'x' to class “POSIXlt”
我做了几个测试来识别格式:
is.Date(df[2,1])
is.POSIXt(df[2,1])
is.instant(df[2,1])
全部给出结果 FALSE。
如果我打印一个日期,我会收到这样的结果:
# A tibble: 1 x 1
`datum`
<dttm>
1 2010-01-20 21:00:00
我试过几次转换:
df$datum <- as.Date(df$datum, origin = "1899-12-30")
df$datum <- as.Date(as.POSIXct(df$datum, 'GMT'))
df$datum <- as.Date(df$datum, format='%Y-%m-%d')
虽然转换后上面的测试结果都是FALSE
如果我进行第一次转换 as.Date(df$datum, origin = "1899-12-30")。 在此之后打印的结果是:
# A tibble: 1 x 1
`datum`
<date>
1 2010-01-20
df$datum + 60 gives:
1 2010-03-21
所以它看起来像是一个日期,因为我可以添加 60。
尽管所有测试都给出 FALSE 并且来自 lubridate 的 days_in_month 仍然给出上述错误。
如何将日期转换为 lubridate 可以处理的正确格式?
非常感谢!
您被 data.frame
和 tbl_df
之间的 [
差异所困扰。阅读您的文件(出现在评论中),我最终看到:
df <- readxl::read_excel("example dates.xlsx")
df
# # A tibble: 3 x 2
# datum datum2
# <dttm> <dttm>
# 1 2010-01-01 13:25:00 2010-12-22 23:53:40
# 2 2010-01-23 13:30:00 2011-01-07 23:09:10
# 3 2010-02-16 21:45:00 2011-03-19 01:00:52
# for everybody else
df <- structure(list(datum = structure(c(1262352300, 1264253400, 1266356700), class = c("POSIXct", "POSIXt"), tzone = "UTC"), datum2 = structure(c(1293062020.704, 1294441750.08, 1300496452.128), class = c("POSIXct", "POSIXt"), tzone = "UTC")), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
我们能否同意尝试一次转换整个帧没有意义?
as.Date(df)
# Error in as.Date.default(df) :
# do not know how to convert 'df' to class "Date"
愚蠢的问题。好吧,让我们看看其他变体会发生什么。
df$datum
# [1] "2010-01-01 13:25:00 UTC" "2010-01-23 13:30:00 UTC" "2010-02-16 21:45:00 UTC"
as.Date(df$datum)
# [1] "2010-01-01" "2010-01-23" "2010-02-16"
df[2,1]
# # A tibble: 1 x 1
# datum
# <dttm>
# 1 2010-01-23 13:30:00
as.Date(df[2,1])
# Error in as.Date.default(df[2, 1]) :
# do not know how to convert 'df[2, 1]' to class "Date"
使用简单的 data.frame
,[2,1]
将 return 一个标量,而不是一个框架,因此这在基数 R 中是有意义的:
as.data.frame(df)[2,1]
# [1] "2010-01-23 13:30:00 UTC"
as.Date(as.data.frame(df)[2,1])
# [1] "2010-01-23"
所以问题是 tibble
迫使你明确表示你想从一个框架下降到 scalar/vector.
坦率地说,这通常是一件好事。在处理 "normal"(非 tibble
)帧并且您想查看一组列时,as.data.frame(df[,1:2])
,R 总是 return 是 data.frame
。不幸的是,如果您以编程方式定义列并且它 return 是单个列,那么 [
默认情况下会将它从一个帧减少到一个向量:as.data.frame(df)[,1]
。您可以使用 drop=
、ala as.data.frame(df[,1,drop=FALSE])
来防止这种自动强制转换。许多人(包括我自己)认为这是一个错误:df[,cols]
应该依赖于始终 return 相同类型的对象,无论它是 20 列还是只有 1 列。 (我知道它这样做是有原因的,我并不是在责备最初的 R 开发人员。)
因此导致您出错的 问题 是 tibble
要求您在将 tbl_df
子集化为单个单元格时明确说明。如果您想在单个单元格上工作,请使用 df$datum[2]
或 df[2,1][[1]]
强制它。如果您想处理整个专栏,那么 df$datum
。所有这些都直接与 as.Date
一起工作,因为它知道如何处理 POSIXt
(本机)和 numeric
/integer
(以及 origin=
的向量).不幸的是,df[,1]
的 tibble 不会 return 向量,因此 as.Date
不知道如何处理它。
底线:
as.Date(df$datum[2])
# [1] "2010-01-23"
as.Date(df[2,1][[1]])
# [1] "2010-01-23"
as.Date(df$datum)
# [1] "2010-01-01" "2010-01-23" "2010-02-16"