【问题标题】:How to convert yyyy-mm-dd h:m:s to dd-mm-yyyy h:m in R?如何在 R 中将 yyyy-mm-dd h:m:s 转换为 dd-mm-yyyy h:m?
【发布时间】:2021-08-14 16:33:00
【问题描述】:

处理两个数据集,其中日期列为字符,日期格式为 dd-mm-yyyy hh:mm,另一个数据集的日期格式为 yyyy-mm-dd hh:mm:ss。 我正在尝试使用 as.date() 将第二个格式更改为 dd-mm-yyyy hh:mm

但是这些列正在变成 N/A 行。

例如:

m09_2020$started_at <- as_datetime(m09_2020$started_at, format = "%d-%m-%Y %H:%M") 

我也不明白为什么在读取到 R 后日期格式会发生变化。Excel 中数据集中的日期格式是 dd-mm-yyyy hh:mm:ss 但在读取到 r 后它会更改为yyyy-mm-dd hh:mm:ss 为那几个月。这很奇怪。 我该怎么办?

【问题讨论】:

  • 如果我不得不猜测源 csv 文件中的某些日期格式不正确,但很难知道,因为您没有提供最小数据集供我们测试。
  • 如果没有更可重复性,这将很难测试或建议修复。以下是一些很好的链接,为如何做到这一点提供了建议:stackoverflow.com/q/5963269minimal reproducible examplestackoverflow.com/tags/r/info。请阅读这些内容,然后回来edit您的问题。谢谢!
  • 据我所知,没有任何行会为which(total_trips$started_at == "2020-10-01") 返回 TRUE。我没有看到任何列的任何转换为​​真正的日期值,并且所有值似乎都是字符而不是实际的 R 日期时间。投票结束。
  • @IRTFM 当我在 8 月、6 月和 7 月使用它时,它会显示值。这就是我想说的,除了这三个月之外,我没有看到使用上述代码的任何其他月份数据
  • @r2evans 好的,谢谢,我会调查并做必要的事情,谢谢!

标签: r csv date tidyverse lubridate


【解决方案1】:

我会使用ymd_hmsymd_hm

library(lubridate)
date1 <- "2019-01-01 22:05:00"
date2 <- "2019-01-01 22:05"
ymd_hms(date1)==ymd_hm(date2)
[1] TRUE

ymd_hms(date1)
[1] "2019-01-01 22:05:00 UTC"

如您所见,我只是提供了一个人们可以在他们身边复制的最小示例。请在下一个问题中这样做。

干杯

【讨论】:

  • 嘿,感谢您的建议,但问题是我想将 yyyy-mm-dd hh:mm:ss 的日期格式更改为 dd-mm-yyyy hh:mm 你所显示的保留日期格式相同。同样在尝试 dmy_hm(date) 时,我收到错误警告:所有格式都无法解析。没有找到格式那么我还能做什么?
  • 请举例说明您的确切日期
【解决方案2】:

背景

在 R 中处理日期和日期时间时,lubridate 包是您的朋友。据我所知,YYYY-MM-DD 通常比 DD-MM-YYYY(或更糟糕的 MM-DD-YYYY)更受欢迎,并且通常是日期时间的默认格式。这是有道理的,因为这样日期时间组件是根据层次结构排列的,并且可以仅根据数值对多个值进行排序,如果使用没有实际日期/日期时间格式的数据(例如,以字符格式,或如果在其他程序中工作)。

所以,我认为 MS Excel 和 R 之间的日期格式值 看起来 不同的原因是,一旦 R 检测到/被告知它是日期格式,它可能默认为 YYYY-MM -DD外观。然而,根据我的经验,Excel 因日期和时间的误导性外观而臭名昭著,有时甚至无法解释。即使 Excel 将日期显示为 DD-MM-YYYY(或您设置的任何内容),它实际上可能不会以这种格式存储。如果您在文本编辑器中查看 .csv 版本,而不是在不告诉您的情况下尝试智能并更改值外观的 Excel,这可能会变得很明显。底线是:如果您遇到问题并且涉及 Excel,请不要相信 Excel。

在 R 中导入日期和日期时间

现在,谈谈你的问题。

  • 因此,我们决定 YYYY-MM-DD 是显示日期和日期时间的首选方式,并且通常是 R 和 lubridate 中的默认设置。
  • 如果您在 R 中有日期/日期时间数据,最好确保 R 知道这一点并以日期时间而不是字符格式存储值。如果您想操作、修改或可视化数据,这将特别有用。

首先我加载lubridate 包,然后以 YYYY-MM-DD HH:MM:SS 和 DD-MM-YYYY HH:MM:SS 格式写出一些示例值。

library(lubridate)

tibble(
  date1 = "2019-01-01 22:05:00", 
  date2 = "02-01-2019 16:45:00"
) %>% 
  {. ->> my_dates}

# # A tibble: 1 x 2
# date1               date2              
# <chr>               <chr>              
# 2019-01-01 22:05:00 02-01-2019 16:45:00

请注意,两个日期时间都是字符格式,如列名下的 &lt;chr&gt; 所示。

要将这些转换为日期时间格式,我们使用ymd_hms() 和朋友或as_datetime()lubridate 函数。正如?as_datetime?ymd_hms 所见,这些函数采用字符或数字格式的日期时间,并将它们转换为日期时间格式 - 它们不是用于修改现有日期时间格式的日期时间的显示方式(与设置 CRS 和重新投影空间数据之间的重要区别。

ymd_hms() 采用字符格式的日期时间,必须year-month-d ay hour-minute-s第二种格式,并将其转换为日期时间格式。如果日期时间字符不是该格式,则必须使用与字符格式匹配的不同函数,例如dmy_hms()mdy_hm() 等。因此,让我们使用适当的函数将这些字符中的每一个转换为日期时间格式:

my_dates %>% 
  mutate(
    date1 = ymd_hms(date1), 
    date2 = dmy_hms(date2)
  ) %>% 
  {. ->> my_dates_dttm}

my_dates_dttm

# # A tibble: 1 x 2
# date1               date2              
# <dttm>              <dttm>             
# 2019-01-01 22:05:00 2019-01-02 16:45:00

或者,我们可以使用as_datetime() 并使用符号和符号outlined here 指定日期时间的确切格式。在本例中,%d 表示日期编号,%m 表示月份编号,%Y 表示年份编号(大写 Y 表示 4 位版本,小写为 2 位),%H 是小时数,%M 是分钟数(注意大写 - 不同于月份数),%S 是秒数。

my_dates %>% 
  mutate(
    date1 = as_datetime(date1, format = '%Y-%m-%d %H:%M:%S'),
    date2 = as_datetime(date2, format = '%d-%m-%Y %H:%M:%S')
  ) %>% 
  {. ->> my_dates_dttm}

# # A tibble: 1 x 2
# date1               date2              
# <dttm>              <dttm>             
# 2019-01-01 22:05:00 2019-01-02 16:45:00

这些函数不能用于尝试转换日期时间的显示方式;如果你很幸运,你会得到NA,如果你不走运,你会得到格式不正确的数据。这就是All formats failed to parse. No formats found.等常见错误的来源,这经常发生在你使用dmy()而不是ymd(),或者指定format = 部分as_datetime()错误时;因为您告诉 R 年值是日值,例如数字 2019 不能是一天(最多 31)或一个月(最多 12)。例如,如果我们在date2 上错误地使用ymd_hms() 而不是dmy_hms(),我们会收到一条错误消息,并且日期时间格式的值为NA

my_dates %>% 
  mutate(
    date1 = ymd_hms(date1),
    date2 = ymd_hms(date2)
  )

# # A tibble: 1 x 2
# date1               date2 
# <dttm>              <dttm>
# 2019-01-01 22:05:00 NA    
# Warning message:
# Problem with `mutate()` column `date2`.
# i `date2 = ymd_hms(date2)`.
# i All formats failed to parse. No formats found.

或者更糟糕的是,您混淆了日和月,而 R 没有意识到,因为这两个数字都小于 12,并且是月或日的可接受值。没有警告或错误消息,R 很高兴。这会在操作日期时间或计算时间差等时引起巨大的麻烦。

my_dates %>% 
  mutate(
    date1 = ymd_hms(date1),
    date2 = mdy_hms(date2)
  )

# # A tibble: 1 x 2
# date1               date2              
# <dttm>              <dttm>             
# 2019-01-01 22:05:00 2019-02-01 16:45:00

好吧,够了厄运和忧郁,回到我们格式化前后的示例数据。

my_dates
# # A tibble: 1 x 2
# date1               date2              
# <chr>               <chr>              
# 2019-01-01 22:05:00 02-01-2019 16:45:00

my_dates_dttm
# # A tibble: 1 x 2
# date1               date2              
# <dttm>              <dttm>             
# 2019-01-01 22:05:00 2019-01-02 16:45:00

所以,my_datesmy_dates_dttm 之间有两个区别。

  1. 两列现在都采用&lt;dttm&gt; 格式,而不是&lt;chr&gt;(写在列名下)
  2. 因为两列现在都是 R 的日期时间格式,所以它们默认为 YYYY-MM-DD HH:MM:SS 显示样式。我建议让它们保持这种状态,然后继续您的计算/操作。

以不同的格式显示日期和日期时间

但是,如果您想以不同的格式显示日期时间,您可以使用format() 函数来实现。您必须使用我们在上面as_datetime() 中使用的相同符号指定您希望它们如何打印。

请注意,这会以字符格式返回日期时间,因此这对于任何计算或操作都没有多大用处,而应仅用作标签。

my_dates_dttm %>% 
  mutate(
    date1_dmy = format(date1, format = '%d-%m-%Y %H:%M:%S')
  )

# # A tibble: 1 x 3
# date1               date2               date1_dmy          
# <dttm>              <dttm>              <chr>              
# 2019-01-01 22:05:00 2019-01-02 16:45:00 01-01-2019 22:05:00

因为format() 返回一个字符,所以您选择的格式不需要是标准的日期时间格式。例如,这里我们只是混淆了日期时间的不同组成部分:

my_dates_dttm %>% 
  mutate(
    date1_jumble = format(date1, format = '%S/%b-%H:%y-%d.%M')
  ) %>% 
  {. ->> my_dates_jumbled}

my_dates_jumbled

# # A tibble: 1 x 3
# date1               date2               date1_jumble      
# <dttm>              <dttm>              <chr>             
# 2019-01-01 22:05:00 2019-01-02 16:45:00 00/Jan-22:19-01.05

但是,这并不妨碍我们转换回日期时间格式 - 如果我们知道打印的确切格式。

my_dates_jumbled %>% 
  mutate(
    date_1_unjumble = as_datetime(date1_jumble, format = '%S/%b-%H:%y-%d.%M')
  )

# # A tibble: 1 x 4
# date1               date2               date1_jumble       date_1_unjumble    
# <dttm>              <dttm>              <chr>              <dttm>             
# 2019-01-01 22:05:00 2019-01-02 16:45:00 00/Jan-22:19-01.05 2019-01-01 22:05:00

更多信息

R for Data Science 一书是学习 R 的绝佳资源,如果您要使用此类数据,我强烈建议您阅读并完成 Chapter 16 - Dates and times 中的示例。

【讨论】:

    猜你喜欢
    • 2014-05-28
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 2011-03-18
    相关资源
    最近更新 更多