在大型数据框中转换为日期时如何为缺少日期和月份的杂乱日期数据指定日期和月份
How to specify day and month for messy date data with missing day and month when converting to date in large data frame
我有一个超过 10 万行的大型日期框架。日期列包含多种格式的日期,例如 "%m/%d/%Y"
、"%Y-%m"
、"%Y"
和 "%Y-%m-%d"
。我可以将这些全部转换为 parse_date_time()
来自 lubridate
的日期。
dates <- c("05/10/1983","8/17/2014","1953-12","1975","2001-06-17")
parse_date_time(dates, orders = c("%m/%d/%Y","%Y-%m","%Y","%Y-%m-%d"))
[1] "1983-05-10 UTC" "2014-08-17 UTC" "1953-12-01 UTC" "1975-01-01 UTC" "2001-06-17 UTC"
但是如您所见,这会将缺少日期的日期设置为该月的第一天,将缺少月份和日期的日期设置为该年的第一天。如何分别将它们设置为 15 日和 6 月 15 日?
使用 nchar
检查日期向量和 paste
缺少什么。
library(lubridate)
dates <- c("05/10/1983","8/17/2014","1953-12","1975","2001-06-17")
dates <- ifelse(nchar(dates) == 4, paste(dates, "06-15", sep = "-"),
ifelse(nchar(dates) == 7, paste(dates, 15, sep = "-"), dates))
dates
#[1] "05/10/1983" "8/17/2014" "1953-12-15" "1975-06-15"
#[5] "2001-06-17"
parse_date_time(dates, orders = c("%m/%d/%Y","%Y-%m","%Y","%Y-%m-%d"))
#[1] "1983-05-10 UTC" "2014-08-17 UTC" "1953-12-15 UTC"
#[4] "1975-06-15 UTC" "2001-06-17 UTC"
另一种解决方案是使用索引向量,同样基于 nchar
。
n <- nchar(dates)
dates[n == 4] <- paste(dates[n == 4], "06-15", sep = "-")
dates[n == 7] <- paste(dates[n == 7], "15", sep = "-")
dates
#[1] "05/10/1983" "8/17/2014" "1953-12-15" "1975-06-15"
#[5] "2001-06-17"
如您所见,结果与 ifelse
相同。
这是另一种方法 - 基于 orders
:
library(lubridate)
dates <- c("05/10/1983","8/17/2014","1953-12","1975","2001-06-17")
parseDates <- function(x, orders = c('mdY', 'dmY', 'Ymd', 'Y', 'Ym')){
fmts <- guess_formats(x, orders = orders)
dte <- parse_date_time(x, orders = fmts[1], tz = 'UTC')
if(!grepl('m', fmts[1]) ){
dte <- dte + days(165)
return(dte)
}
if(!grepl('d', fmts[1]) ){
dte <- dte + days(14)
}
return(dte)
}
输出
> parseDates(dates[4])
[1] "1975-06-15 UTC"
> parseDates(dates[3])
[1] "1953-12-15 UTC"
对于不同的日期格式,您只需更改 orders
参数,其余的使用 lubridate
完成。
希望对您有所帮助!
我有一个超过 10 万行的大型日期框架。日期列包含多种格式的日期,例如 "%m/%d/%Y"
、"%Y-%m"
、"%Y"
和 "%Y-%m-%d"
。我可以将这些全部转换为 parse_date_time()
来自 lubridate
的日期。
dates <- c("05/10/1983","8/17/2014","1953-12","1975","2001-06-17")
parse_date_time(dates, orders = c("%m/%d/%Y","%Y-%m","%Y","%Y-%m-%d"))
[1] "1983-05-10 UTC" "2014-08-17 UTC" "1953-12-01 UTC" "1975-01-01 UTC" "2001-06-17 UTC"
但是如您所见,这会将缺少日期的日期设置为该月的第一天,将缺少月份和日期的日期设置为该年的第一天。如何分别将它们设置为 15 日和 6 月 15 日?
使用 nchar
检查日期向量和 paste
缺少什么。
library(lubridate)
dates <- c("05/10/1983","8/17/2014","1953-12","1975","2001-06-17")
dates <- ifelse(nchar(dates) == 4, paste(dates, "06-15", sep = "-"),
ifelse(nchar(dates) == 7, paste(dates, 15, sep = "-"), dates))
dates
#[1] "05/10/1983" "8/17/2014" "1953-12-15" "1975-06-15"
#[5] "2001-06-17"
parse_date_time(dates, orders = c("%m/%d/%Y","%Y-%m","%Y","%Y-%m-%d"))
#[1] "1983-05-10 UTC" "2014-08-17 UTC" "1953-12-15 UTC"
#[4] "1975-06-15 UTC" "2001-06-17 UTC"
另一种解决方案是使用索引向量,同样基于 nchar
。
n <- nchar(dates)
dates[n == 4] <- paste(dates[n == 4], "06-15", sep = "-")
dates[n == 7] <- paste(dates[n == 7], "15", sep = "-")
dates
#[1] "05/10/1983" "8/17/2014" "1953-12-15" "1975-06-15"
#[5] "2001-06-17"
如您所见,结果与 ifelse
相同。
这是另一种方法 - 基于 orders
:
library(lubridate)
dates <- c("05/10/1983","8/17/2014","1953-12","1975","2001-06-17")
parseDates <- function(x, orders = c('mdY', 'dmY', 'Ymd', 'Y', 'Ym')){
fmts <- guess_formats(x, orders = orders)
dte <- parse_date_time(x, orders = fmts[1], tz = 'UTC')
if(!grepl('m', fmts[1]) ){
dte <- dte + days(165)
return(dte)
}
if(!grepl('d', fmts[1]) ){
dte <- dte + days(14)
}
return(dte)
}
输出
> parseDates(dates[4])
[1] "1975-06-15 UTC"
> parseDates(dates[3])
[1] "1953-12-15 UTC"
对于不同的日期格式,您只需更改 orders
参数,其余的使用 lubridate
完成。
希望对您有所帮助!