R - 格式化数据框中的日期 - 十进制和字符值的混合

R - Formatting dates in dataframe - mix of decimal and character values

我在数据框中有一个日期列。我已经使用 openxlsx 将此 df 读入 R。当我使用 typeof(df$date).

时,该列是 'seen' 作为字符向量

该列包含多种格式的日期信息,我希望将其转换为一种格式。

#Example
date <- c("43469.494444444441", "12/31/2019 1:41 PM", "12/01/2019  16:00:00")

#What I want -updated
fixed <- c("2019-04-01", "2019-12-31", "2019-12-01")

我尝试了很多解决方法,包括 openxlsx::ConvertToDatelubridate::parse_date_timelubridate::date_decimal

openxlsx::ConvertToDate到目前为止效果最好,但它只会采用一种格式并为其他格式强制 NA

更新

我意识到我实际上将上述输出日期之一弄错了。 值 43469.494444444441 应转换为 2019-04-01。

这是分两步执行此操作的一种方法。单独更改 excel 日期,并以不同方式更改所有其他日期。如果你有更多格式的日期可以添加到parse_date_time.

temp <- lubridate::parse_date_time(date, c('mdY IMp', 'mdY HMS'))
temp[is.na(temp)] <- as.Date(as.numeric(date[is.na(temp)]), origin = "1899-12-30")

temp
#[1] "2019-01-04 11:51:59 UTC" "2019-12-31 13:41:00 UTC" "2019-12-01 16:00:00 UTC"
as.Date(temp)
#[1] "2019-01-04" "2019-12-31" "2019-12-01"

您可以使用辅助函数来规范化日期,这可能比 lubridate 稍快一些。

weird origins in MS Excel 取决于平台。因此,如果数据是从不同平台导入的,您可能需要使用虚拟变量。

normDate <- Vectorize(function(x) {
if (!is.na(suppressWarnings(as.numeric(x))))  # Win excel
  as.Date(as.numeric(x), origin="1899-12-30")
else if (grepl("A|P", x))
  as.Date(x, format="%m/%d/%Y %I:%M %p")
else
  as.Date(x, format="%m/%d/%Y %R")
})

如需其他日期格式,只需添加另一个 else if。可以通过 ?strptime.

找到格式规范

然后只需使用 as.Date() 和通常的来源。

res <- as.Date(normDate(date), origin="1970-01-01")
# 43469.494444444441   12/31/2019 1:41 PM 12/01/2019  16:00:00 
#       "2019-01-04"         "2019-12-31"         "2019-12-01"
class(res)
# [1] "Date"

编辑: 要实现特定的输出格式,请使用format,例如

format(res, "%Y-%d-%m")
# 43469.494444444441   12/31/2019 1:41 PM 12/01/2019  16:00:00 
#       "2019-04-01"         "2019-31-12"         "2019-01-12" 

format(res, "%Y/%d/%m")
# 43469.494444444441   12/31/2019 1:41 PM 12/01/2019  16:00:00 
#       "2019/04/01"         "2019/31/12"         "2019/01/12" 

要查找代码类型 ?strptime