1

Is there any loops for the mentioned below code?

library(lubridate)

Val_Date <- as.Date("2022-01-1", format = "%Y-%m-%d")
Inception_Date <- as.Date("2012-01-01", format = "%Y-%m-%d")

a  <- data.frame(Date = seq(Inception_Date, Val_Date, by = "years"))
b  <- data.frame(Date = seq(Inception_Date + years(1), Val_Date, by = "years"))
c  <- data.frame(Date = seq(Inception_Date + years(2), Val_Date, by = "years"))
d  <- data.frame(Date = seq(Inception_Date + years(3), Val_Date, by = "years"))
e  <- data.frame(Date = seq(Inception_Date + years(4), Val_Date, by = "years"))
f  <- data.frame(Date = seq(Inception_Date + years(5), Val_Date, by = "years"))
g  <- data.frame(Date = seq(Inception_Date + years(6), Val_Date, by = "years"))
h  <- data.frame(Date = seq(Inception_Date + years(7), Val_Date, by = "years"))
i  <- data.frame(Date = seq(Inception_Date + years(8), Val_Date, by = "years"))
j  <- data.frame(Date = seq(Inception_Date + years(9), Val_Date, by = "years"))
k  <- data.frame(Date = seq(Inception_Date + years(10), Val_Date, by = "years"))

complete <- rbind(a, b, c, d, e, f, g, h, i, j, k)

In k my Inception_Date + year(10) is equal to val_Date, so I need loop because every time my val date increases I want add a new line of code.

Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
Zohaib
  • 13
  • 4
  • It's not quite clear to me what exactly you are trying to achieve. But when iterating over a set of elements (here: dates), a for() loop seems to be the more straight-forward solution: ```for(currentdate in a){print(currentdate)}``` – Where's my towel Mar 14 '23 at 12:16
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Mar 14 '23 at 12:50

4 Answers4

2

I suggest to create once your sequence of dates, then create the sequence of index numbers using sequence with from = and then subset the dates based on that sequence.

dates <- seq(as.Date("2012-01-1"),as.Date("2022-01-1"), by ="years")

n <- length(dates)

dates[sequence(n:1, from = 1:n)]

# [1] "2012-01-01" "2013-01-01" "2014-01-01" "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01" "2013-01-01"
# [13] "2014-01-01" "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01" "2014-01-01" "2015-01-01" "2016-01-01"
# [25] "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01" "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01"
# [37] "2021-01-01" "2022-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01" "2017-01-01" "2018-01-01" "2019-01-01"
# [49] "2020-01-01" "2021-01-01" "2022-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01"
# [61] "2020-01-01" "2021-01-01" "2022-01-01" "2021-01-01" "2022-01-01" "2022-01-01"
Merijn van Tilborg
  • 5,452
  • 1
  • 7
  • 22
1
  • A recursive solution:
date_seq_recur <- function(start, end) {
  if(start <= end)
    c(seq(start, end, by = "year"), date_seq_recur(start + years(1), end))
}

date_seq_recur(Inception_Date, Val_Date)
  • while-loop:
date_seq_while <- function(start, end) {
  date <- as.Date(numeric())
  while(start <= end) {
    date <- c(date, seq(start, end, by = "year"))
    start <- start + years(1)
  }
  return(date)
}

date_seq_while(Inception_Date, Val_Date)
Outout
#  [1] "2012-01-01" "2013-01-01" "2014-01-01" "2015-01-01" "2016-01-01" "2017-01-01"
#  [7] "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01" "2013-01-01"
# [13] "2014-01-01" "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01"
# [19] "2020-01-01" "2021-01-01" "2022-01-01" "2014-01-01" "2015-01-01" "2016-01-01"
# [25] "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01"
# [31] "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01"
# [37] "2021-01-01" "2022-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01"
# [43] "2020-01-01" "2021-01-01" "2022-01-01" "2017-01-01" "2018-01-01" "2019-01-01"
# [49] "2020-01-01" "2021-01-01" "2022-01-01" "2018-01-01" "2019-01-01" "2020-01-01"
# [55] "2021-01-01" "2022-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01"
# [61] "2020-01-01" "2021-01-01" "2022-01-01" "2021-01-01" "2022-01-01" "2022-01-01"
Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
  • What if i a want a one more column to be added which repeats (length(seq(Inception_Date, Val_Date, by = "years")) times year of Inception_Date. – Zohaib Mar 14 '23 at 13:45
  • For example the like this code Int_Yr_0 = length(seq(as.Date(Inception_Date),as.Date(Val_Date), by ="years")) a<- data.frame(Int_Yr = seq(as.Date(Inception_Date),as.Date(Val_Date), by ="years"), Loss_Yr = rep(as.numeric(format(Inception_Date,'%Y'),Int_Yr_0))) like this has a second column loss_year – Zohaib Mar 14 '23 at 13:51
  • @Zohaib `dates <- seq(Inception_Date, Val_Date, by = "years")`; `rep(format(dates, '%Y'), rev(seq_along(dates)))` – Darren Tsai Mar 14 '23 at 14:42
0
for (i in unique(a)) {
  print(i)
# Edit to adrees OP's comment
  x=as.Date(a[i,1])
  seq(x,length=2,by='1 year')[2]
}

As for storing results you can use a list and then do.call to make it into a dataframe.

mylist <- list()
for (i in 1:length(a$Date)) {
  mylist[[i]]=a[i,1]
}

do.call('rbind',mylist)

Another option

for (i in seq.Date(from = Inception_Date,to=Val_Date,by='year')) {
  print(i)
# do other stuff
}
dandrews
  • 967
  • 5
  • 18
  • That's fine, just add a call inside either of those loops to advance the date and it will do so on each iteration automatically. I just used these simple examples because you don't provide enough information for me to know exactly what you are trying to achieve. – dandrews Mar 14 '23 at 12:40
  • I added two line to the first loop for one option, see here https://stackoverflow.com/questions/3312964/how-to-subtract-years – dandrews Mar 14 '23 at 12:44
  • Note that OP deleted their comment and updated the question, so these answers may now fall outside of the purvue of the new question. – dandrews Mar 14 '23 at 17:07
0

Use time_seq_v() from timeplyr which is a vectorised time sequence function that can handle lubridate periods/durations, as well as non-integer increments.

# remotes::install_github("NicChr/timeplyr")
library(timeplyr)
library(lubridate)
Val_Date <- as.Date("2022-01-1", format = "%Y-%m-%d")
Inception_Date <- as.Date("2012-01-01", format = "%Y-%m-%d")

time_seq_v(Inception_Date + years(0:10), Val_Date, units = "years", num = 1)
#>  [1] "2012-01-01" "2013-01-01" "2014-01-01" "2015-01-01" "2016-01-01"
#>  [6] "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01"
#> [11] "2022-01-01" "2013-01-01" "2014-01-01" "2015-01-01" "2016-01-01"
#> [16] "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01"
#> [21] "2022-01-01" "2014-01-01" "2015-01-01" "2016-01-01" "2017-01-01"
#> [26] "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01"
#> [31] "2015-01-01" "2016-01-01" "2017-01-01" "2018-01-01" "2019-01-01"
#> [36] "2020-01-01" "2021-01-01" "2022-01-01" "2016-01-01" "2017-01-01"
#> [41] "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01"
#> [46] "2017-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01"
#> [51] "2022-01-01" "2018-01-01" "2019-01-01" "2020-01-01" "2021-01-01"
#> [56] "2022-01-01" "2019-01-01" "2020-01-01" "2021-01-01" "2022-01-01"
#> [61] "2020-01-01" "2021-01-01" "2022-01-01" "2021-01-01" "2022-01-01"
#> [66] "2022-01-01"

Created on 2023-03-16 with reprex v2.0.2

Nick Chr
  • 3
  • 3