r-如何在数据帧的多列中将不同的日期格式转换为单一格式

  • 本文关键字:格式 日期 单一 转换 数据帧 r date
  • 更新时间 :
  • 英文 :


我有一个数据框架,其中包含分散在列中的不同格式的日期,我希望将它们标准化为单一格式。我可以对异构日期的单个向量进行标准化,如在d中,通过在向量(如formats(中定义可能的日期格式并将其传递给as.Date:

d <- c("01-02-2009","01/04/2009","15-Jan-2019", "12-12-2020")
formats <- c("%d-%m-%Y", "%d/%m/%Y", "%d-%b-%Y")
format(as.Date(d, format = formats), "%d-%b-%Y")
[1] "01-Feb-2009" "01-Apr-2009" "15-Jan-2019" "12-Dez-2020"

但这对数据帧不起作用:

df <- data.frame(Transaction = c("01-Mar-2015", "31-01-2012", "15/01/1999"), 
Delivery = c("01-02-2018", "01/08/2016", "17-09-2007"), 
Return = c("27/11/2009", "22-Jan-2013", "20-Nov-1987"))

在这里,标准化只是部分起作用:

df[,1:3] <- lapply(df[,1:3], function(x) format(as.Date(x, format = formats), "%d-%b-%Y"))
df
Transaction    Delivery      Return
1        <NA> 01-Feb-2018        <NA>
2        <NA> 01-Aug-2016        <NA>
3        <NA>        <NA> 20-Nov-1987

如何在整个数据帧中将日期标准化为%d-%b-%Y格式?

使用mutate_all,您可以使用lubridate中的parse_date_time函数将数据帧的所有字符列转换为单一日期格式,并在orders参数中传递格式列表。

然后,您可以使用format:将这些日期格式化为所需的输出

library(lubridate)
library(dplyr)
formats <- c("%d-%m-%Y", "%d/%m/%Y", "%d-%b-%Y")
df %>% mutate_all( ~parse_date_time(., orders = formats)) %>%
mutate_all(~format(., "%d-%b-%Y"))
Transaction    Delivery      Return
1 01-Mar-2015 01-Feb-2018 27-Nov-2009
2 31-Jan-2012 01-Aug-2016 22-Jan-2013
3 15-Jan-1999 17-Sep-2007 20-Nov-1987

使用apply可以执行:

library(lubridate)
apply(df, 2, function(x) format(parse_date_time(x, orders = formats), "%d-%b-%Y"))
Transaction   Delivery      Return       
[1,] "01-Mar-2015" "01-Feb-2018" "27-Nov-2009"
[2,] "31-Jan-2012" "01-Aug-2016" "22-Jan-2013"
[3,] "15-Jan-1999" "17-Sep-2007" "20-Nov-1987"

它能回答你的问题吗?


注意:parse_date_time正在为lubridate version 1.7.8工作。对于lubridate version 1.7.4,可以使用parse_date并用format替换orders

问题是列中的formats与已经创建的不同。所以,我们需要像这样的东西

as.Date(df$Transaction, format = c("%d-%b-%Y", "%d-%m-%Y", "%d/%m/%Y"))
#[1] "2015-03-01" "2012-01-31" "1999-01-15"

即OP指定的CCD_ 18是

formats
#[1] "%d-%m-%Y" "%d/%m/%Y" "%d-%b-%Y"

如果我们检查"交易"列

df$Transaction
#[1] 01-Mar-2015 31-01-2012  15/01/1999 

它包括现有格式中没有的%d-%m-%Y%d/%m/%Y


此外,为了更清楚,传递的矢量format正在对format进行元素比较

as.Date(df$Transaction, format = c("%d-%b-%Y", "%d/%m/%Y"))
#[1] "2015-03-01" NA           NA   

即,通过传递"%d/%m/%Y",它应该与第三个条目匹配,但因为它是元素比较,所以它与第二个元素进行检查,然后对向量格式进行循环,因为它的长度小于"事务"列的长度

这意味着,如果我们的数据集是1e6行,那么它期望1e6格式应该与每个元素匹配。


或使用anytime中的anydate

library(anytime)
addFormats(c('%d-%m-%Y', '%d/%m/%Y'))
df[] <- lapply(df,  function(x) format(anydate(x), "%d-%b-%Y"))
df
#  Transaction    Delivery      Return
#1 01-Mar-2015 01-Feb-2018 27-Nov-2009
#2 31-Jan-2012 01-Aug-2016 22-Jan-2013
#3 15-Jan-1999 17-Sep-2007 20-Nov-1987

最新更新