在R中处理错误解析的日期-时间数据

k3bvogb1  于 2023-10-13  发布在  其他
关注(0)|答案(2)|浏览(100)

我正在使用read_excel从Excel将数据阅读到R中。其中一列date_time具有混合格式,并作为字符向量读入。下面是行的示例。

date_time <- c(
  45144.4762962963,
  45144.475138888891,
  "14-08-2023 10:38:54 AM",
  "14-08-2023 10:37:03 AM",
  "24-05-2023 9:29:44 AM",
  "24-05-2023 9:27:18 AM",
  45113.462395833332,
  45113.461261574077,
  "15-05-2023 1:47:12 PM",
  44988.399664351855
)

data <- tibble(date_time)

混合格式的原因似乎是,当数据最初被解析到Excel表中时,它期望的格式是mm-dd-yyyy hh:mm:ss,但实际数据是dd-mm(切换)。结果是,如果第一个数字大于12,则将其解析为Excel中的文本变量(例如,data的第3行)。然而,当日期不明确时,它会以Excel的日期格式进行解析,日期和月份错误地切换(例如,data的第1行应为2023年6月8日上午11:25:52,而不是2023年8月6日)。
如何将其转换为具有正确日期的一致dttm对象?我想我可以通过编辑我正在阅读的Excel文件来做到这一点,但由于这将是一个持续的问题,我想在R中找到一种方法来做到这一点。

ccgok5k5

ccgok5k51#

可能有一种更整洁的方法来完成这项工作,但是下面的代码将为您的格式组合完成这项工作。
首先用parse_date_time转换简单的一个,然后将数字转换为日期时间,并按正确的顺序阅读日期。

data <- tibble(date_time) |>
  mutate(
    new_date_time1 = parse_date_time(
      date_time,
      orders = c("%d-%m-%Y %I:%M:%S %p"),
      tz = "UTC"
    ),
    new_date_time2 = parse_date_time(
      as.character(
        as.POSIXct(
          as.Date(
            as.numeric(date_time),
              origin =
                "1899-12-30")
    )),
    orders = c("%Y-%d-%m %H:%M:%S"))) |>
  transmute(fixed_date_time = if_else(is.na(new_date_time1),
                                      new_date_time2,
                                      new_date_time1))

# A tibble: 10 × 1
#    fixed_date_time    
#    <dttm>             
#  1 2023-06-08 11:25:52
#  2 2023-06-08 11:24:12
#  3 2023-08-14 10:38:54
#  4 2023-08-14 10:37:03
#  5 2023-05-24 09:29:44
#  6 2023-05-24 09:27:18
#  7 2023-06-07 11:05:50
#  8 2023-06-07 11:04:13
#  9 2023-05-15 13:47:12
# 10 2023-03-03 09:35:31
lzfw57am

lzfw57am2#

我将创建两个功能。第一个是将数字日期转换为R日期时间对象:

get_date_from_numeric <- function(date, origin = "1899-12-30") {
    date_day_month_switched <- as.POSIXct(origin, tz = "UTC") +
        as.difftime(as.numeric(date), units = "days")
    # Switch month and day
    strptime(date_day_month_switched, "%Y-%d-%m %H:%M:%S", tz = "UTC")
}

请参阅here了解为什么Excel的起源是1899年12月30日(在Windows上)。
我们还创建了一个函数来转换字符日期:

get_date_from_string  <- function(date) {
    strptime(date, "%d-%m-%Y %I:%M:%S %p", tz = "UTC")
}

参见this answer了解strptime()符号的含义。
字符串函数将为数字日期返回NA,反之亦然。这意味着我们可以coalesce()结果:

library(dplyr)

data |>
    mutate(
        numeric_date = get_date_from_numeric(date_time),
        string_date = get_date_from_string(date_time),
        clean_date = coalesce(numeric_date, string_date)
    ) |>
    select(-numeric_date, -string_date)

# # A tibble: 10 × 2
#    date_time              clean_date
#    <chr>                  <dttm>
#  1 45144.4762962963       2023-06-08 11:25:52
#  2 45144.4751388889       2023-06-08 11:24:12
#  3 14-08-2023 10:38:54 AM 2023-08-14 10:38:54
#  4 14-08-2023 10:37:03 AM 2023-08-14 10:37:03
#  5 24-05-2023 9:29:44 AM  2023-05-24 09:29:44
#  6 24-05-2023 9:27:18 AM  2023-05-24 09:27:18
#  7 45113.4623958333       2023-06-07 11:05:50
#  8 45113.4612615741       2023-06-07 11:04:13
#  9 15-05-2023 1:47:12 PM  2023-05-15 13:47:12
# 10 44988.3996643519       2023-03-03 09:35:31

注意:您将收到NAs introduced by coercion警告。这是根据设计-我们期望NA用于无效格式,这就是为什么我们可以coalesce()

相关问题