代码之家  ›  专栏  ›  技术社区  ›  tassones

将yy.mmd(d)日期格式转换为R中的yyyy-mm-dd

  •  0
  • tassones  · 技术社区  · 3 年前

    我使用的是一种旧的日期格式,前两位数字代表20世纪的年份。小数点后的前两位为月份(即01-12),小数点后第三位和第四位为当天(即01-31)。问题是,以零结尾的日期(即10、20、30)会去掉后面的零,因此某些日期格式只有三位小数。

    如何恢复尾随的零,以便将旧的日期格式转换为现代日期格式(即yyyy-mm-dd)?

    示例:

    library(tidyverse)
    
    # Example data
    
    xx <- data.frame(yr_mo_da = c('89.1208','89.1209','89.121', '89.1211'))
    
    # My attempt to extract year, month, day from the old date format
    # NOTE how the day is not extracted properly because there is not a fourth decimal place on Dec. 10
    
    xx$year <- as.numeric(gsub("\\..*","",xx$yr_mo_da))
    xx$month <- as.numeric(sub("^[0-9]+\\.([0-9]{2}).*", "\\1", xx$yr_mo_da))
    xx$day <- as.numeric(sub("^[0-9]+\\.[0-9]{2}([0-9]{2}).*", "\\1", xx$yr_mo_da))
    xx
    #>   yr_mo_da year month    day
    #> 1  89.1208   89    12  8.000
    #> 2  89.1209   89    12  9.000
    #> 3   89.121   89    12 89.121
    #> 4  89.1211   89    12 11.000
    
    # Create modern date format
    
    xx <- xx %>%
      mutate(year = year + 1900,
             Date = make_date(year,month,day)) %>%
      select(-c(yr_mo_da,year,day,month))
    xx
    #>         Date
    #> 1 1989-12-08
    #> 2 1989-12-09
    #> 3       <NA>
    #> 4 1989-12-11
    

    正确的输出应该如下所示:

    xx
    #>         Date
    #> 1 1989-12-08
    #> 2 1989-12-09
    #> 3 1989-12-10
    #> 4 1989-12-11
    

    创建于2023-09-05 reprex v2.0.2

    3 回复  |  直到 3 年前
        1
  •  2
  •   margusl    3 年前

    您可以先用“0”右键填充这些字符串:

    library(dplyr)
    library(stringr)
    library(lubridate)
    
    xx <- data.frame(yr_mo_da = c('89.1208','89.1209','89.121', '89.1211'))
    xx |> 
      mutate(yr_mo_da_pad = str_pad(yr_mo_da, width = max(str_length(yr_mo_da)), side = "right", pad = "0"),
             date = ymd(yr_mo_da_pad))
    #>   yr_mo_da yr_mo_da_pad       date
    #> 1  89.1208      89.1208 1989-12-08
    #> 2  89.1209      89.1209 1989-12-09
    #> 3   89.121      89.1210 1989-12-10
    #> 4  89.1211      89.1211 1989-12-11
    

    创建于2023-09-05 reprex v2.0.2

        2
  •  1
  •   Dirk is no longer here    3 年前

    在解析之前,您需要将数字数据转换回文本。只有基数R的一种方法是:

    > xx <- data.frame(yr_mo_da = c('89.1208','89.1209','89.121', '89.1211'))  
    > xx$year <- trunc(as.numeric(xx$yr_mo_da))
    > xx$moda <- (as.numeric(xx$yr_mo_da) - xx$year)*10000
    > xx$date <- strptime(sprintf("%02.0f%04.0f", xx$year, xx$moda), "%y%m%d")
    > xx
      yr_mo_da year moda       date
    1  89.1208   89 1208 1989-12-08
    2  89.1209   89 1209 1989-12-09
    3   89.121   89 1210 1989-12-10
    4  89.1211   89 1211 1989-12-11
    > 
    

    如果你最初的分配没有强制字符值,我们可以跳过双字符 as.numeric()

    推荐文章