我正在寻找快速解决方案以将日期四舍五入到一年的最后一天,但该年份始于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万的矢量,我确实确实需要尽可能快的功能。
没有必要逐步进行操作,可以使用矢量化功能。
例如,这会快很多:
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知道它应该只看一小部分,并且结果仅在最后合并。