【发布时间】:2019-03-14 04:53:01
【问题描述】:
我有大约 34000 个日期向量,我必须更改日期和移动月份。我已经尝试过循环并使用mapply 函数,但它非常慢。
这是我所拥有的一个例子:
library(lubridate)
list_dates = replicate(34000,seq(as.Date("2019-03-14"),length.out = 208,by = "months"),simplify = F)
new_day = round(runif(34000,1,30))
new_day[sample(1:34000,10000)] = NA
new_dates = mapply(FUN = function(dates,day_change){
day(dates) = ifelse(is.na(rep(day_change,length(dates))),day(dates),rep(day_change,length(dates)))
dates = as.Date(ifelse(is.na(rep(day_change,length(dates))),dates,dates%m-%months(1)),origin = "1970-01-01")
return(dates)
},dates = list_dates,day_change = as.list(new_day),SIMPLIFY = F)
变量new_dates 应该包含一个原始日期列表,这些日期相应地移动到变量new_day。 side中的函数是这样工作的:
- 如果
new_day与 NA 不同,则会将日期更改为新日期 - 如果
new_day与NA 不同,它将把日期的月份移到后面。
我愿意接受任何可以提高速度的解决方案,无论使用何种包(如果它们在 CRAN 中)。
编辑
因此,基于 cmets,我将示例简化为包含 2 个日期的 2 个日期向量列表,并创建了一个新日期的手动向量:
list_dates = replicate(2,seq(as.Date("2019-03-14"),length.out = 2,by = "months"),simplify = F)
new_day = c(9,NA)
这是原始输入(变量 list_dates):
[[1]]
[1] "2019-03-14" "2019-04-14"
[[2]]
[1] "2019-03-14" "2019-04-14"
mapply 函数的预期输出是:
[[1]]
[1] "2019-02-09" "2019-03-09"
[[2]]
[1] "2019-03-14" "2019-04-14"
如您所见,第一个日期向量已更改为第 9 天,并且每个日期滞后一个月。第二个日期向量没有改变,因为 new_dates 是 NA 对于那个值。
【问题讨论】:
-
您能否将输入减少到 10 个日期,并显示您正在尝试做什么以及您的预期输出?
-
除了 Ronak 的评论,请使用固定的随机种子来确保样本数据和预期输出的可重复性。我也不确定你所说的 “它将把日期的月份移到后面”是什么意思。你的意思是说
new_month = old_month - 1对于list_dates元素的所有日期? -
您是否想使用来自
lubridate的函数day或索引您传递给mapply的参数day存在一些歧义。如果是后者,那么您应该使用方括号[]。在任何情况下,请避免将变量命名为与您打算使用的函数相同 -
我将问题更新为尽可能少。 @Rohit 感谢关于 day 参数的评论,这是我从原始函数中遇到的一个错误,已经更改它。