如何使用lubridate解析无效日期?

yacmzcpb  于 2024-01-03  发布在  其他
关注(0)|答案(2)|浏览(139)

我需要解析日期,并且有一个类似“31/02/2018”的案例:

library(lubridate)
> dmy("31/02/2018", quiet = T)
[1] NA

字符串
这是有意义的,因为2月31日并不存在。是否有方法将字符串“31/02/2018”解析为例如2018-02-28?这样就不会得到NA,而是得到实际日期?
谢谢.

dxxyhpgq

dxxyhpgq1#

我们可以写一个函数,假设你只会有可能比实际日期更高的日期,并且总是具有相同的格式。

library(lubridate)

get_correct_date <- function(example_date) {
  #Split vector on "/" and get 3 components (date, month, year)
  vecs <- as.numeric(strsplit(example_date, "\\/")[[1]])

  #Check number of days in that month
  last_day_of_month <-  days_in_month(vecs[2])

  #If the input date is higher than actual number of days in that month
  #replace it with last day of that month
  if (vecs[1] > last_day_of_month)
    vecs[1] <- last_day_of_month

  #Paste the date components together to get new modified date
  dmy(paste0(vecs, collapse = "/"))
}

get_correct_date("31/02/2018")
#[1] "2018-02-28"

get_correct_date("31/04/2018")
#[1] "2018-04-30"

get_correct_date("31/05/2018")
#[1] "2018-05-31"

字符串
通过小的修改,您可以调整日期,如果他们有不同的格式,甚至如果一些日期小于第一个日期。

crcmnpdw

crcmnpdw2#

以下是一些基本解决方案:

**1)**使用read.table将部分分为V1,V2和V3,然后在月初创建日期。为此减去一并添加一天。对于问题中的示例,它是前一个月最后一天的31天。

d <- c("30/02/2008", "31/02/2008", "15/02/2008")

d2 <- d |> read.table(text = _, sep = "/") |>
  with(as.Date(sprintf("%d-%02d-01", V3, V2)) - 1 + V1) 
d2
## [1] "2008-03-01" "2008-03-02" "2008-02-15"

字符串

**2)**如果在无效时想要月底(eom),则以普通方式计算日期,并计算每月的第一天(fom),然后通过向fom添加31来计算月底(eom),添加31以到达下一个月,用cut得到该月的第一个月,减去1得到该月的利息结束。如果用普通方法计算的日期无效,则该月的eom将由pmin接起。

d <- c("30/02/2008", "31/02/2008", "15/02/2008")

fom <- d |> sub("..", "01", x = _) |> as.Date(format = "%d/%m/%Y")
eom <- as.Date(cut(fom + 31, "month")) - 1
pmin(as.Date(d, "%d/%m/%Y"), eom, na.rm = TRUE)
## [1] "2008-02-29" "2008-02-29" "2008-02-15"

相关问题