关于dplyr:R:向日期添加月份的有效方法?

R: efficient ways to add months to dates?

我有一个数百万行的data.table,其中一列是date列。我想为该列中的所有日期添加12个月并创建一个新列。所以我使用dplyr和lubridate软件包,例如

1
2
3
library(dplyr)
library(lubridate)
new_data <- data %>% mutate(date12m = date %m+% months(12))

这有效,但是对于大型数据集来说非常慢。我想念什么吗?如何加快速度?对于这样一个简单的任务,我通常不希望R运行超过10分钟。

编辑:

我注意到我的解决方案已经比使用as.yearmon更有效。感谢Beauvel上校提供的解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
a <- data.frame(date = rep(today(),1000000))


func = function(u) {
  d = as.Date(as.yearmon(u)+1, frac=1)
  if(day(u)>day(d)) return(d)
  day(d) = day(u)
  d
}

pt <- proc.time()
a <- a %>% mutate(date12m = func(date))
data.table::timetaken(pt)


pt <- proc.time()
a <- a %>% mutate(date12m = date %m+% 12)
data.table::timetaken(pt)


只需将1与month

相加

1
2
3
4
5
x=seq.Date(from=as.Date("2007-01-01"), to=as.Date("2014-12-12"), by="day")
month(x) = month(x) + 1

#> head(x)
#[1]"2007-02-01""2007-02-02""2007-02-03""2007-02-04""2007-02-05""2007-02-06"

Edit:按照@akrun注释,这里是解决方案,使用zoo包中的as.yearmon。诀窍是在获取下个月最后一个日期的日期时进行快速检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
library(zoo)

func = function(u)
{
    d = as.Date(as.yearmon(u)+1/12, frac=1)
    if(day(u)>day(d)) return(d)
    day(d) = day(u)
    d
}

x=as.Date(c("2014-01-31","2015-02-28","2013-03-02"))
#> as.Date(sapply(x, func))
#[1]"2014-02-28""2015-03-28""2013-04-02"


我也在R中处理大数据帧,可以使用包DescTools,它具有一个名为AddMonths(date,NoOfMonths)的函数。

对我来说效果很好。

1
2
3
4
5
> a <- ymd("2011-09-9")
> b <- AddMonths(a,1)
> b

[1]"2011-10-09"