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::ConvertToDate
、lubridate::parse_date_time
、lubridate::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
。
我在数据框中有一个日期列。我已经使用 openxlsx 将此 df 读入 R。当我使用 typeof(df$date)
.
该列包含多种格式的日期信息,我希望将其转换为一种格式。
#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::ConvertToDate
、lubridate::parse_date_time
、lubridate::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
。