【问题标题】:How to specify day and month for messy date data with missing day and month when converting to date in large data frame在大数据框中转换为日期时如何为缺少日期和月份的杂乱日期数据指定日期和月份
【发布时间】:2018-11-22 06:34:36
【问题描述】:

我有一个超过 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看字符数好像不错。如果nchar(dates) == 4,粘贴"-06-15"。然后如果nchar &lt; 8 粘贴在"-15" 上。也许做一个快速的gsub 将所有/ 替换为- 以获得稍微更统一的格式。

标签: r date lubridate


【解决方案1】:

使用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 相同。

【讨论】:

  • nchar() 替换步骤之后,是否应该删除替换的格式?似乎它们无论如何都被忽略了。
  • @user29609 你说的是第二种解决方案吗?结果仍然需要parse_date_time。如果要保留原始向量,请分配给不同的向量dates2 &lt;- dates,然后对其进行转换。
  • 不,抱歉。我的意思是order 参数中指定的不再需要的格式,例如%Y%Y-%m
  • @user29609 orders 参数仍然需要,你应该保留它。
【解决方案2】:

这是另一种方法 - 基于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 完成。

希望这有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多