簡體   English   中英

有沒有更優雅的方法來使用 lubridate 將兩位數的年份轉換為四位數的年份?

[英]Is there a more elegant way to convert two-digit years to four-digit years with lubridate?

如果日期向量有兩位數的年份,則mdy()將 00 到 68 之間的年份轉換為 21 世紀年份,將 69 到 99 之間的年份轉換為 20 世紀年份。 例如:

library(lubridate)    
mdy(c("1/2/54","1/2/68","1/2/69","1/2/99","1/2/04"))

給出以下輸出:

Multiple format matches with 5 successes: %m/%d/%y, %m/%d/%Y.
Using date format %m/%d/%y.
[1] "2054-01-02 UTC" "2068-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC" "2004-01-02 UTC"

我可以通過從不正確的日期中減去 100 將 2054 和 2068 變成 1954 和 1968 來解決這個問題。解析過程本身?

更新:在@JoshuaUlrich 將我指向strptime我發現了這個問題,它處理的問題與我的類似,但使用的是基礎 R。

R 中日期處理的一個很好的補充似乎是在日期解析函數中處理兩位數日期的世紀選擇截止點的某種方式。

這是一個允許您執行此操作的函數:

library(lubridate)
x <- mdy(c("1/2/54","1/2/68","1/2/69","1/2/99","1/2/04"))


foo <- function(x, year=1968){
  m <- year(x) %% 100
  year(x) <- ifelse(m > year %% 100, 1900+m, 2000+m)
  x
}

試試看:

x
[1] "2054-01-02 UTC" "2068-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC"
[5] "2004-01-02 UTC"

foo(x)
[1] "2054-01-02 UTC" "2068-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC"
[5] "2004-01-02 UTC"

foo(x, 1950)
[1] "1954-01-02 UTC" "1968-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC"
[5] "2004-01-02 UTC"

這里的神奇之處在於使用模運算符%%來返回除法的小數部分。 所以1968 %% 100產生 68。

我剛剛經歷了這個完全相同的錯誤/功能。

我最終編寫了以下兩個快速函數來幫助將 excel 類型的日期(這是我最常用的)轉換為 R 可以使用的日期。

接受的答案沒有任何問題——只是我不想過多地加載包裹。

一、分裂替換歲月的幫手……

year1900 <- function(dd_y, yrFlip = 50)
{
    dd_y <- as.numeric(dd_y)
    dd_y[dd_y > yrFlip] <- dd_y[dd_y > yrFlip] + 1900
    dd_y[dd_y < yrFlip] <- dd_y[dd_y < yrFlip] + 2000
    return(dd_y)
}

它由“修復”您的 excel 日期的函數使用,具體取決於類型:

XLdate <- function(Xd, type = 'b-Y')
{
    switch(type,
        'b-Y' = as.Date(paste0(substr(Xd, 5, 9), "-", substr(Xd, 1, 3), "-01"), format = "%Y-%b-%d"),
        'b-y' = as.Date(paste0(year1900(substr(Xd, 5, 6)), "-", substr(Xd, 1, 3), "-01"), 
                        format = "%Y-%b-%d"),
        'Y-b' = as.Date(paste0(substr(Xd, 1, 3), "-", substr(Xd, 5, 9), "-01"), format =     "%Y-%b-%d")
        )
}

希望這可以幫助。

另一種選擇是:

xxx <- c("01-Jan-54","01-Feb-68","01-Aug-69","01-May-99","01-Jun-04", "
       31-Dec-68","01-Jan-69", "31-Dec-99")

.

dmy(paste0(sub("\\d\\d$","",xxx) , ifelse( (tt <- 
   sub("\\d\\d-\\D\\D\\D-","",xxx)  ) > 20 ,paste0("19",tt),paste0("20",tt))))

盡管沒有任何解決方案既優雅又簡短。 我認為如果 lubridate 只是添加一個選項來指定截止日期會更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM