【问题标题】:Working with difficult AM/PM formats and REGEX with lubridate in R在 R 中使用 lubridate 处理困难的 AM/PM 格式和 REGEX
【发布时间】:2022-02-14 02:12:47
【问题描述】:

大家好,我希望每个人都过得很好,我正在尝试在 R 上使用 lubridate 中的一些 AM/PM 格式,但我似乎无法找到合适的解决方案,希望你们能纠正我的意思并帮助我请!

我有一个巨大的数据集,它具有非常罕见的日期时间格式,格式如下:

首先是代表日期的数字,其次是月份的缩写,甚至月份完全拼写为 12H 时间格式和字符串“a.m”。或“下午”甚至在“点”之间或缺少更多空格的组合,然后例如“a.m”来举例,请看一下这个向量:

dates<-c("02 dec 05:47 a. m", 
"7 November 09:47 p. m.",
"3  jul 12:28 a.m.", 
"23 sept 08:53 a m.", 
"7 may 09:05 PM")

这些占数据集中 95% 以上的罕见日期时间格式我一直在尝试在 R 上使用 lubridate 我正在尝试使用该函数

ydm_hm(paste(2021,dates))

这是因为所有日期都是 2021 年,但我总是得到:

[1] NA                        NA                        NA                       
[4] NA                        "2021-05-07 21:05:00 UTC"
Warning message:
 4 failed to parse. 

解析失败的 4 个给了我 NAS,唯一一个解析正确的我确实注意到这个有 PM 或 AM 作为没有点的大写字母,但大多数时候我的格式是这样的:

ydm_hm("7 may 09:05 p.m.")

这给了我 NAS...

所以我觉得让这个日期锻炼的唯一方法是改变结构并使用 REGEX 转换所有“a.m”。只有在分析数据后我才意识到所有“pm”或“a.m”组合成“AM”和“PM”。字符串出现在 12H 时间格式之后的 1 个或 2 个空格之后,其长度始终为 5 个字符,因此应该考虑使用 REGEX 的模式如下

字符串将以一两个数字开头,然后是空格,然后是字母(对于缩写或完整拼写的月份,之后将有空格,然后是 5 个字符(即 12H 时间格式),然后将有字母空格和点对于所有可能的 a.m 和 p.m 格式,但我尝试过没有运气来转换日期的结构。如果你们能帮助我,我会非常感激,我不知道 R 中是否有一种方法或另一个包可以甚至在不使用正则表达式的情况下解决此问题,所以感谢大家的帮助!

我想要的输出是:

"2021-12-02 05;47:00 UTC"
"2021-11-07 09:47:00 UTC"
"2021-07-03 12:28:00 UTC"
"2021-09-23 08:53:00 UTC"
"2021-05-07 21:05:00 UTC"

【问题讨论】:

  • 您好!感谢您的回复我使用代码 ydm_hm(paste(2021,dates)) 因为提交的日期时间没有年份,所以我将 2021 年粘贴到其中...因为在 R 中我似乎无法在 lubridate 中找到乐趣仅使用日期和月份以及小时和分钟之类的 dm_hm() 或者我尝试过但没有运气,非常感谢

标签: r regex datetime lubridate data-wrangling


【解决方案1】:

在这种情况下,来自parsedateparse_date 有效

library(parsedate)
parse_date(paste(2021, dates))

-输出

[1] "2021-12-02 05:47:00 UTC"
[2] "2021-11-07 09:47:00 UTC" 
[3] "2021-07-03 12:28:00 UTC"
[4] "2021-09-23 08:53:00 UTC" 
[5] "2021-05-07 21:05:00 UTC"

或者如果第二个值应该是PM,使用str_remove去掉空格

library(stringr)
parse_date(paste(2021, str_remove_all(dates,
    "(?<=[A-Za-z])[. ]+(?=[A-Za-z])")))
[1] "2021-12-02 05:47:00 UTC" 
[2] "2021-11-07 21:47:00 UTC" 
[3] "2021-07-03 00:28:00 UTC" 
[4] "2021-09-23 08:53:00 UTC" 
[5] "2021-05-07 21:05:00 UTC"

对于ydm_hm,问题在于am/pm 格式之一显示没有. 的空格,这可能无法解析。我们可以通过删除空格来改变格式

library(lubridate)
library(stringr)
ydm_hm(paste(2021, str_remove_all(dates,
    "(?<=[A-Za-z])[. ]+(?=[A-Za-z])")))
[1] "2021-12-02 05:47:00 UTC" 
[2] "2021-11-07 21:47:00 UTC" 
[3] "2021-07-03 00:28:00 UTC" 
[4] "2021-09-23 08:53:00 UTC" 
[5] "2021-05-07 21:05:00 UTC"

【讨论】:

  • 非常感谢你是独一无二的!感谢您教我有关此库的知识,这很有效,我衷心感谢!
  • 我觉得这个答案不对?
  • @langtang 我检查了 OP 的预期输出,结果是一样的
  • 好的,但我想我不明白为什么 OP 预计下午时间是 09:47,而不是 21:47。或者上午时间是 12:28 而不是 00:28。我看到你编辑的帖子现在有我期望的正确时间
  • @akrun parsedate 包非常适合此类任务。谢谢分享!
【解决方案2】:

既然你提出了正则表达式的问题,我想我可以尝试一种方法来做到这一点

library(stringr)

# get boolean for pm dates
pm = str_detect(dates,"(?<=\\d\\d:\\d\\d\\s{1,2})[pP]",)

# convert dates to dates without am/pm
dates = str_extract(dates,"^.*:\\d\\d")

# add pm back to pm dates and am to am dates
dates[pm] <- paste(dates[pm], "PM")
dates[!pm] <- paste(dates[!pm], "AM")

# now your orignal approach works
ydm_hm(paste(2021,dates))

输出

[1] "2021-12-02 05:47:00 UTC" "2021-11-07 21:47:00 UTC" "2021-07-03 00:28:00 UTC" "2021-09-23 08:53:00 UTC"
[5] "2021-05-07 21:05:00 UTC"

【讨论】:

  • 嘿!太棒了,感谢您花时间教我这个正则表达式公式你呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-17
  • 1970-01-01
  • 2011-05-27
相关资源
最近更新 更多