簡體   English   中英

如果 R 中缺少,則從列中提取日期並添加年份

[英]Extracting a date from a column and adding the year if missing in R

我正在嘗試從文本中提取日期並在數據集中創建一個新列。 在 A1 列中以不同的格式輸入日期(mm-dd-yy 或 mm-dd)。 我需要找到一種方法來識別 A1 列中的日期,然后在缺少年份時添加年份。 到目前為止,無論格式如何,我都能夠提取日期; 但是,當我在新列 A2 上使用 as.Date 時,具有 mm-dd 格式的日期變為<NA> 我知道對於這種情況可能沒有直接的解決方案,但是解決方法(可推廣到更大的數據集)會很棒。 從 2019 年 9 月到 2020 年 8 月,這一年將是 go。此外,我不確定為什么我在as.Date function 中使用的格式無法控制日期的顯示方式。 后一個問題並不那么重要,但我對 R function 的行為感到驚訝。 tidyverse 中的解決方案將不勝感激。

library(tidyverse)
library(stringr)
    
db <- data.frame(A1 = c("review 11/18", "begins 12/4/19", "3/5/20", NA, "deadline 09/5/19", "9/3")) 

db %>% mutate(A2 = str_extract(A1, "[0-9/0-9]+")) 
#                A1      A2
#1     review 11/18   11/18
#2   begins 12/4/19 12/4/19
#3           3/5/20  3/5/20
#4             <NA>    <NA>
#5 deadline 09/5/19 09/5/19
#6              9/3     9/3
    
db %>% mutate(A2 = str_extract(A1, "[0-9/0-9]+")) %>% 
       mutate(A2 = A2 %>% as.Date(., "%m/%d/%y"))

 #               A1         A2
 #   1     review 11/18       <NA>
 #   2   begins 12/4/19 2019-12-04
 #   3           3/5/20 2020-03-05
 #   4             <NA>       <NA>
 #   5 deadline 09/5/19 2019-09-05
 #   6              9/3       <NA>

好吧,這既不是一個漂亮、簡潔或整潔的解決方案,但它確實有效,並且在模塊化方面應該是靈活的。

library(tidyverse)

db <- data.frame(A1 = c("review 11/18", "begins 12/4/19", "3/5/20", NA, "deadline 09/5/19", "9/3")) 
db <- db %>% mutate(A2 = str_extract(A1, "[0-9/0-9]+"), A2 = str_extract(A1, "[0-9/0-9]+"))

test1 <- unlist(lapply(str_split(db$A2, "/", n = 3), function(x) length(x)))
test2 <- lapply(str_split(db$A2, "/", n = 3), function(x) as.numeric(x))

if(test1 == 2){
  if(test2[[1]] >= 9){
    db$A2 <- ifelse(test = between(nchar(db$A2), 3, 5) & !is.na(db$A2), yes = paste0(db$A2, "/19"), no = db$A2)
  }
  if(test2[[1]] < 9){
    db$A2 <- ifelse(test = between(nchar(db$A2), 3, 5) & !is.na(db$A2), yes = paste0(db$A2, "/20"), no = db$A2)
  }
}

db <- db %>% mutate(A2 = A2 %>% as.Date(., "%m/%d/%y"))
db

                A1         A2
1     review 11/18 2019-11-18
2   begins 12/4/19 2019-12-04
3           3/5/20 2020-03-05
4             <NA>       <NA>
5 deadline 09/5/19 2019-09-05
6              9/3 2019-09-03

也許:

library(tidyverse)

db <- data.frame(A1 = c("review 11/18", "begins 12/4/19", "3/5/20", NA, "deadline 09/5/19", "9/3")) 

#year from september to august 2019

(db <- 
 db %>% 
  mutate(A2 = str_extract(A1, '[\\d\\d/]+'),
         A2 = if_else(str_count(A2, '/') == 1 & as.numeric(str_extract(A2, '\\d+')) > 8, paste0(A2, '/19'), A2),
         A2 = if_else(str_count(A2, '/') == 1 & as.numeric(str_extract(A2, '\\d+')) <= 8, paste0(A2, '/20'), A2),
         A2 = as.Date(A2, "%m/%d/%y")) )             
#>                 A1         A2
#> 1     review 11/18 2019-11-18
#> 2   begins 12/4/19 2019-12-04
#> 3           3/5/20 2020-03-05
#> 4             <NA>       <NA>
#> 5 deadline 09/5/19 2019-09-05
#> 6              9/3 2019-09-03

代表 package (v2.0.1) 於 2021 年 11 月 21 日創建

對於許多正則表達式場景,我喜歡rematch2 package。

第一個模式嘗試匹配完整的 m/d/y 值。 第二種模式試圖匹配部分 m/d 值(此外,它將月份與日期分開,因此它可以確定它應該是 2019 年還是 2020 年)。

一旦這些部分被隔離,rest 只是一系列小步驟。

db |> 
  rematch2::bind_re_match(from = A1, "^.*?(?<mdy>\\d{1,2}/\\d{1,2}/\\d{2})$") |> 
  rematch2::bind_re_match(from = A1, "^.*?(?<md_m>\\d{1,2})/(?<md_d>\\d{1,2})$") |> 
  dplyr::mutate(
    md_m  = as.integer(md_m),
    md_y  = dplyr::if_else(9L <= md_m, "19", "20"), # It's 2019 if the month is Sept or later
    md    = sprintf("%i/%s/%s", md_m, md_d, md_y),  # Assemble components
    md    = as.Date(md , "%m/%d/%y"),               # Convert data type
    mdy   = as.Date(mdy, "%m/%d/%y"),               # Convert data type
    
    date = dplyr::coalesce(mdy, md),                # Prefer the mdy if it's not missing
  )

Output:

                A1        mdy md_m md_d md_y         md       date
1     review 11/18       <NA>   11   18   19 2019-11-18 2019-11-18
2   begins 12/4/19 2019-12-04    4   19   20 2020-04-19 2019-12-04
3           3/5/20 2020-03-05    5   20   20 2020-05-20 2020-03-05
4             <NA>       <NA>   NA <NA> <NA>       <NA>       <NA>
5 deadline 09/5/19 2019-09-05    5   19   20 2020-05-19 2019-09-05
6              9/3       <NA>    9    3   19 2019-09-03 2019-09-03

暫無
暫無

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

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