如何将此日期格式转换为 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.frametbl_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"