在R中使用round_date()舍入日期

我尝试在 R 中仅在 yyyy 中转换日期格式 yyyymmdd。如何在 R 中的日期中仅转换数字年份?提出了一个非常有趣的答案,因为它设法让 R 理解将润滑包中的 8 位数条目 (yyyymmdd) 转换为 4 位数年份 (yyyy),这对我来说非常好。

在我用于round_date()它的旧代码中:

   date2<-c('01/01/2000','08/08/2000','16/03/2001','25/12/2000','29/02/2000')
    name<-c('A','B','C','D','E')
    
    df<-data.frame(date2,name)
    
    df2 <- df %>%
      mutate(date2 = dmy(date2)) %>%
      mutate(year_date = round_date(date2,'year'))
    
    df2
    str(df2)

date2<date> name<chr> year_date <date>
2000-01-01    A         2000-01-01      
2000-08-08    B         2001-01-01      
2001-03-16    C         2001-01-01      
2000-12-25    D         2001-01-01      
2000-02-29    E         2000-01-01  

但是当我发现例如日期 2000-08-08 被四舍五入到 2001-01-01 而不是 2001-01-01 时,我的统计分析开始出现问题。

这对我来说是一个非常大的问题,因为考虑到我的数据库中有 1400 多行,属于 2005 年的信息已移至 2006 年。

我注意到年中(六月之后)之后的日期被四舍五入到下一年,这非常糟糕。

如何将 2000-08-08 日期四舍五入到 2000 而不是 2001?

回答

这个(更简单,也只有基础 R)操作不是你想要的吗?

> date2 <- c('01/01/2000','08/08/2000','16/03/2001','25/12/2000','29/02/2000')
> dd <- as.Date(date2, "%d/%m/%Y")
> yd <- format(dd, "%Y-01-01")
> dt <- as.Date(yd)
> D <- data.frame(date2=date2, date=dd, y=yd, d=dt)
> D
       date2       date          y          d   
1 01/01/2000 2000-01-01 2000-01-01 2000-01-01
2 08/08/2000 2000-08-08 2000-01-01 2000-01-01
3 16/03/2001 2001-03-16 2001-01-01 2001-01-01
4 25/12/2000 2000-12-25 2000-01-01 2000-01-01
5 29/02/2000 2000-02-29 2000-01-01 2000-01-01
>   

本质上,我们只是从(解析为日期)Date对象中提取年份组件并追加-01-01

编辑:还有trunc()DateDatetime对象的操作。奇怪的是,多年来的截断仅适用于Datetimetrunc.Date有关更多信息,请参阅帮助页面)所以这也适用:

> as.Date(trunc(as.POSIXlt(dd), "years"))
[1] "2000-01-01" "2000-01-01" "2001-01-01" "2000-01-01" "2000-01-01"
> 

编辑 2: 我们可以在一个更清晰/更简单的解决方案中使用最后一步,其中data.frame包含三列输入数据(作为字符),将数据解析为正确的Date类型和所需的截断年份数据——所有这些都使用基数 R,没有进一步的依赖。当然,如果你可以通过管道和重写它lubridate通过稍微慢的路线(仅事项“大型”数据)相同的结果。

> date2 <- c('01/01/2000','08/08/2000','16/03/2001','25/12/2000','29/02/2000')
> pd <- as.Date(date2, "%d/%m/%Y")
> td <- as.Date(trunc(as.POSIXlt(pd), "years"))
> D <- data.frame(input = date2, parsed = pd, output = td)
> D
       input     parsed     output
1 01/01/2000 2000-01-01 2000-01-01
2 08/08/2000 2000-08-08 2000-01-01
3 16/03/2001 2001-03-16 2001-01-01
4 25/12/2000 2000-12-25 2000-01-01
5 29/02/2000 2000-02-29 2000-01-01
> 

对于真正的“生产”用途,您可能不需要data.frame也不需要保留导致单行的中间结果:

> as.Date(trunc(as.POSIXlt( as.Date(date2, "%d/%m/%Y") ), "years"))
[1] "2000-01-01" "2000-01-01" "2001-01-01" "2000-01-01" "2000-01-01"
> 

这可能是您可以获得的最紧凑和最高效的转换。

  • See my updated answer. Using _typed_ representation makes for safer programming, so I recommend converting to `Date` sooner. You can still use whatever add-on functions from whatever add-on packages you like, but they do use the underlying base R types. They are fundamental building blocks -- and as you can see you can mix and match.

以上是在R中使用round_date()舍入日期的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>