到R中任意确定的开始和结束的结束日期

问题描述 投票:0回答:1

我正在寻找快速解决方案以将日期四舍五入到一年的最后一天,但该年份始于1.10,结束于30.09。因此,当我有2020-04-05时,应将此日期舍入到2020-09-30。当我有2020-12-12时,应该将此日期舍入到2021-09-30。我已经尝试过此功能:

round_date_to_seasons <- function(dates) {
    rounded_dates <- structure(rep(NA_real_, length(dates)), class = "Date")
    for (i in seq.int(1, length.out = length(dates))) {
        if (month(dates[i]) %in% c(10, 11, 12)) {
            year(dates[i]) <- year(dates[i]) + 1
            month(dates[i]) <- 9
            day(dates[i]) <- 30
        } else {
            month(dates[i]) <- 9
            day(dates[i]) <- 30
        }
        rounded_dates[i] <- dates[i]
    }
    rounded_dates
}

但是很慢。如果我正确地进行了填充,则值分配很慢,因此上面代码中的第7、8、9、11、12行以及第14行,但是最后一行还不错。对于长度大于等于1000万的矢量,我确实确实需要尽可能快的功能。

r data.table lubridate
1个回答
0
投票

没有必要逐步进行操作,可以使用矢量化功能。

例如,这会快很多:

library(lubridate)
round_date_to_seasons_new <- function(dates)
{
  as.Date(ifelse(month(dates) %in% 10:12,
         as_date(ISOdate(year(dates) + 1, 9, 30)),
         as_date(ISOdate(year(dates), 10, 1))),
        origin = '1970-01-01')
}

[尽可能使用R中的矢量化函数。

在您的示例中,在循环的每次迭代中,都会检索(多次)整个rounded_dates对象,更改一个元素,然后将所有内容写回到内存中。如果您的函数对整个对象执行某些操作,则这是必需的。但是在这种情况下,第一次迭代仅查看并更改了第一个元素,第二次迭代仅在第二个元素上,依此类推。

如果使用向量化函数,R知道它应该只看一小部分,并且结果仅在最后合并。

© www.soinside.com 2019 - 2024. All rights reserved.