[SOLVED] loop over a function in R

Issue

I have a function called holt_filter that does something and returns a data frame. (function down below)

Its arguments are the original dataset, the initial date, the final date, and the forecast horizon.

so I would like to do something like this:

trends1 <- holt_filter(trends, initial_date="2003 Q1", final_date="2010 Q4", forecast_horizon=4)
trends1 <- trends1 %>%  rename_at(vars(-quarter), function(x) paste0(x,"t_11")) %>% relocate(quarter)

trends2 <- holt_filter(trends1, initial_date = "2003 Q1", final_date = "2011 Q4", forecast_horizon = 4)
trends2 <- trends2 %>% rename_with(~str_replace(., "t_11","t_12")) %>% relocate(quarter)

trends3 <- holt_filter(trends2, initial_date = "2003 Q1", final_date = "2012 Q4", forecast_horizon = 4)
trends3 <- trends3 %>% rename_with(~str_replace(., "t_12","t_13")) %>% relocate(quarter)

.
.
.
trendsi <- holt_filter(trends[i-1], initial_date="2003 Q1", final_date="2020 Q4"

Where trends is the original dataset.

I want to make a loop for this and generate multiple data frames, only varying the final_date argument. This is a vector for all the final dates I want.

dates <- c("2010 Q4","2011 Q4", "2012 Q4", "2013 Q4", "2014 Q4", "2015 Q4","2016 Q4","2017 Q4", "2018 Q4", "2019 Q4", "2020 Q4")

I think I need a double for loop, but I don’t know how to use it.

Thanks in advance!


holt_filter Function

holt_filter <- function(data,initial_date, final_date, forecast_horizon){
  # Filter by date
  require(dplyr, zoo, forecast, lubridate)
  data <- data %>% 
    filter(quarter>= as.yearqtr(initial_date) & 
             quarter<=as.yearqtr(final_date))
  
  # Create a list with time series
  time_series <- lapply(select(data,-quarter), function(t) ts(t, 
                                                              start = c(year(as.yearqtr(initial_date)),quarter(as.yearqtr(initial_date))),
                                                              end=c(year(as.yearqtr(final_date)),quarter(as.yearqtr(final_date))),
                                                              frequency = 4 ))
  
  # Make the forecast
  holt <- lapply(time_series, holt, model="ZAN", damped=T, h=forecast_horizon)
  holt <- lapply(holt, forecast)
  
  
  # Convert to dataframe
  holt=holt %>% as.data.frame() %>% 
    select(contains("Point.Forecast")) %>% rename_with(~str_remove(.,".Point.Forecast")) %>% 
    rownames_to_column(var="quarter") %>% mutate(quarter=as.yearqtr(quarter)) 
  
  # Get a dataframe with original data and forecasted data
  data_out=data %>% bind_rows(data, holt)%>% 
    mutate(date=as.Date(quarter))
  
  data_out <- rbind(data, holt)
  
  # Get the output
  return(data_out)
}

Data

> dput(trends)
structure(list(quarter = structure(c(2003, 2003.25, 2003.5, 2003.75, 
2004, 2004.25, 2004.5, 2004.75, 2005, 2005.25, 2005.5, 2005.75, 
2006, 2006.25, 2006.5, 2006.75, 2007, 2007.25, 2007.5, 2007.75, 
2008, 2008.25, 2008.5, 2008.75, 2009, 2009.25, 2009.5, 2009.75, 
2010, 2010.25, 2010.5, 2010.75, 2011, 2011.25, 2011.5, 2011.75, 
2012, 2012.25, 2012.5, 2012.75, 2013, 2013.25, 2013.5, 2013.75, 
2014, 2014.25, 2014.5, 2014.75, 2015, 2015.25, 2015.5, 2015.75, 
2016, 2016.25, 2016.5, 2016.75, 2017, 2017.25, 2017.5, 2017.75, 
2018, 2018.25, 2018.5, 2018.75, 2019, 2019.25, 2019.5, 2019.75, 
2020), class = "yearqtr"), wti_t = structure(c(3.40327668190002, 
3.46458768844604, 3.52603244781494, 3.58761954307556, 3.6492030620575, 
3.71046233177185, 3.7709367275238, 3.83009004592896, 3.88737964630127, 
3.94229650497437, 3.9943859577179, 4.0432825088501, 4.08874273300171, 
4.13064479827881, 4.16898775100708, 4.20389080047607, 4.23551511764526, 
4.26393270492554, 4.28905296325684, 4.31069278717041, 4.32873487472534, 
4.3433198928833, 4.35502910614014, 4.36495780944824, 4.37446928024292, 
4.38469934463501, 4.39623260498047, 4.40915441513062, 4.42324638366699, 
4.4381251335144, 4.45328521728516, 4.46809720993042, 4.48182201385498, 
4.49368810653687, 4.50299024581909, 4.50911903381348, 4.51154518127441, 
4.50981569290161, 4.50357294082642, 4.4925274848938, 4.47642660140991, 
4.45505428314209, 4.42828607559204, 4.39618062973022, 4.35905838012695, 
4.3175573348999, 4.27268695831299, 4.22586345672607, 4.17881679534912, 
4.13334178924561, 4.09106779098511, 4.05335330963135, 4.02119064331055, 
3.99508142471313, 3.97501063346863, 3.96056962013245, 3.9511137008667, 
3.94587326049805, 3.94400477409363, 3.94459819793701, 3.94672346115112, 
3.94955539703369, 3.95252704620361, 3.95542335510254, 3.95836186408997, 
3.96169018745422, 3.96590781211853, 3.9716465473175, 3.9796416759491
), label = "wti trend component from bw filter", format.stata = "%9.0g"), 
    cpiUSA_t = structure(c(5.20301055908203, 5.21056079864502, 
    5.21812438964844, 5.22571134567261, 5.23333024978638, 5.24098443984985, 
    5.24867153167725, 5.25638389587402, 5.26410722732544, 5.27182149887085, 
    5.27950143814087, 5.28711700439453, 5.29463863372803, 5.30203866958618, 
    5.30929279327393, 5.3163800239563, 5.32328176498413, 5.32997417449951, 
    5.3364315032959, 5.34262657165527, 5.34853792190552, 5.3541522026062, 
    5.3594765663147, 5.3645453453064, 5.36941576004028, 5.37415313720703, 
    5.37881469726562, 5.38344573974609, 5.38808059692383, 5.39274454116821, 
    5.39745187759399, 5.4022011756897, 5.40697526931763, 5.41174411773682, 
    5.41647005081177, 5.42111873626709, 5.4256591796875, 5.43006610870361, 
    5.43432235717773, 5.43841457366943, 5.44233655929565, 5.44608736038208, 
    5.44967412948608, 5.45310735702515, 5.45640134811401, 5.45957660675049, 
    5.4626612663269, 5.46569442749023, 5.46872186660767, 5.47179174423218, 
    5.47494649887085, 5.47822237014771, 5.48164844512939, 5.48524284362793, 
    5.48901319503784, 5.49295568466187, 5.49705791473389, 5.50130176544189, 
    5.50566673278809, 5.51012706756592, 5.51465368270874, 5.51922035217285, 
    5.52380275726318, 5.52838325500488, 5.53295278549194, 5.53750467300415, 
    5.54203939437866, 5.54656267166138, 5.55108642578125), label = "cpiUSA trend component from bw filter", format.stata = "%9.0g"), 
    cpi_t = structure(c(4.15908050537109, 4.16563892364502, 4.17219924926758, 
    4.17877101898193, 4.18536996841431, 4.19202470779419, 4.1987738609314, 
    4.20566940307617, 4.21276378631592, 4.22010898590088, 4.22775220870972, 
    4.23573923110962, 4.24411106109619, 4.25290536880493, 4.26215982437134, 
    4.27190732955933, 4.28217172622681, 4.29296016693115, 4.30425643920898, 
    4.31601190567017, 4.32814264297485, 4.34053707122803, 4.35307264328003, 
    4.36563920974731, 4.37814998626709, 4.39054298400879, 4.40277862548828, 
    4.41483879089355, 4.42671871185303, 4.43842124938965, 4.44995546340942, 
    4.46133184432983, 4.47255373001099, 4.48361492156982, 4.49449920654297, 
    4.50518608093262, 4.5156512260437, 4.52587175369263, 4.53582954406738, 
    4.5455150604248, 4.55492401123047, 4.56405830383301, 4.57291889190674, 
    4.58150196075439, 4.58979034423828, 4.59775638580322, 4.6053638458252, 
    4.61257028579712, 4.61932849884033, 4.62559175491333, 4.63131904602051, 
    4.63648366928101, 4.64107227325439, 4.64508628845215, 4.64853954315186, 
    4.65145826339722, 4.65388011932373, 4.65585041046143, 4.65742254257202, 
    4.65865564346313, 4.65960931777954, 4.66034030914307, 4.66089868545532, 
    4.66132736206055, 4.66166257858276, 4.66193246841431, 4.66216087341309, 
    4.66236686706543, 4.66256237030029), label = "cpi trend component from bw filter", format.stata = "%9.0g"), 
    rDep_t = structure(c(0.0359907001256943, 0.0349562615156174, 
    0.0339597687125206, 0.0330456756055355, 0.0322683714330196, 
    0.0316815711557865, 0.0313298515975475, 0.0312435291707516, 
    0.0314371325075626, 0.0319106914103031, 0.0326525755226612, 
    0.0336427949368954, 0.0348555110394955, 0.0362593047320843, 
    0.0378152914345264, 0.039474543184042, 0.0411769226193428, 
    0.0428547151386738, 0.044441495090723, 0.0458807088434696, 
    0.0471302084624767, 0.0481640547513962, 0.0489722304046154, 
    0.0495574288070202, 0.0499301664531231, 0.0501054525375366, 
    0.0501026771962643, 0.0499471835792065, 0.0496709644794464, 
    0.0493108406662941, 0.0489045232534409, 0.0484859794378281, 
    0.0480823814868927, 0.0477141067385674, 0.0473965927958488, 
    0.047142006456852, 0.0469598546624184, 0.0468570552766323, 
    0.0468380264937878, 0.046904768794775, 0.0470569133758545, 
    0.0472915954887867, 0.0476032570004463, 0.0479832850396633, 
    0.0484195314347744, 0.0488961711525917, 0.049394678324461, 
    0.0498958639800549, 0.0503816679120064, 0.0508363842964172, 
    0.0512480549514294, 0.0516093857586384, 0.0519173704087734, 
    0.052173275500536, 0.0523846074938774, 0.0525668896734715, 
    0.0527425780892372, 0.0529368445277214, 0.053172592073679, 
    0.0534672737121582, 0.0538319759070873, 0.0542714186012745, 
    0.0547842681407928, 0.0553636737167835, 0.055998433381319, 
    0.0566749982535839, 0.0573797486722469, 0.0581007860600948, 
    0.0588292218744755), label = "rDep trend component from bw filter", format.stata = "%9.0g"), 
    cash_t = structure(c(8.59445476531982, 8.6219596862793, 8.64947891235352, 
    8.67704296112061, 8.70470333099365, 8.73252964019775, 8.76058483123779, 
    8.78891658782959, 8.81754112243652, 8.84644222259521, 8.8755578994751, 
    8.90479183197021, 8.93404579162598, 8.96323490142822, 8.99229717254639, 
    9.02118682861328, 9.04987525939941, 9.07836055755615, 9.10666942596436, 
    9.13485431671143, 9.16297626495361, 9.19108295440674, 9.21919250488281, 
    9.24728965759277, 9.27535820007324, 9.30342388153076, 9.33158397674561, 
    9.35999870300293, 9.38886737823486, 9.41841793060303, 9.44888019561768, 
    9.48047542572021, 9.5134105682373, 9.5478687286377, 9.58399200439453, 
    9.62187194824219, 9.66155052185059, 9.70302581787109, 9.74623775482178, 
    9.79106426239014, 9.83733463287354, 9.88484668731689, 9.93338012695312, 
    9.98270416259766, 10.0325679779053, 10.0826921463013, 10.1327524185181, 
    10.1823863983154, 10.2312145233154, 10.2788715362549, 10.325023651123, 
    10.3693971633911, 10.4117956161499, 10.4521017074585, 10.4902677536011, 
    10.5262994766235, 10.5602474212646, 10.5921945571899, 10.6222620010376, 
    10.6506004333496, 10.6773929595947, 10.7028455734253, 10.7271776199341, 
    10.7506122589111, 10.7733707427979, 10.7956571578979, 10.8176498413086, 
    10.839485168457, 10.8612518310547), label = "cash trend component from bw filter", format.stata = "%9.0g"), 
    m1_t = structure(c(9.22379779815674, 9.26027679443359, 9.29678535461426, 
    9.33334350585938, 9.36996078491211, 9.40663719177246, 9.443359375, 
    9.4800968170166, 9.51680374145508, 9.55342960357666, 9.58992004394531, 
    9.62622833251953, 9.66231441497803, 9.69815921783447, 9.73377132415771, 
    9.76918315887451, 9.80445098876953, 9.83963680267334, 9.87478446960449, 
    9.90990543365479, 9.94497108459473, 9.97992897033691, 10.0147199630737, 
    10.0493049621582, 10.0836954116821, 10.1179599761963, 10.152195930481, 
    10.186484336853, 10.2208662033081, 10.2553453445435, 10.2898979187012, 
    10.3244867324829, 10.3590631484985, 10.3935880661011, 10.4280309677124, 
    10.4623680114746, 10.4965753555298, 10.5306234359741, 10.5644769668579, 
    10.5980854034424, 10.6313848495483, 10.6643133163452, 10.6968202590942, 
    10.728853225708, 10.7603549957275, 10.7912616729736, 10.8215074539185, 
    10.8510246276855, 10.8797674179077, 10.9077224731445, 10.9349050521851, 
    10.9613351821899, 10.9870223999023, 11.0119428634644, 11.0360431671143, 
    11.0592470169067, 11.0814762115479, 11.1026706695557, 11.1228103637695, 
    11.1419115066528, 11.1600294113159, 11.1772575378418, 11.1937198638916, 
    11.2095623016357, 11.2249279022217, 11.2399606704712, 11.254789352417, 
    11.2695121765137, 11.2841920852661), label = "m1 trend component from bw filter", format.stata = "%9.0g"), 
    m2_t = structure(c(9.83384323120117, 9.87546920776367, 9.91716003417969, 
    9.95895099639893, 10.0008544921875, 10.042854309082, 10.0849170684814, 
    10.1269845962524, 10.1689834594727, 10.2108278274536, 10.2524347305298, 
    10.2937240600586, 10.3346252441406, 10.3750972747803, 10.4151372909546, 
    10.4547815322876, 10.4940977096558, 10.5331592559814, 10.5720272064209, 
    10.6107292175293, 10.6492700576782, 10.6876373291016, 10.7258367538452, 
    10.7639102935791, 10.8019552230835, 10.8401107788086, 10.8785133361816, 
    10.91725730896, 10.9563694000244, 10.9958200454712, 11.0355262756348, 
    11.0753688812256, 11.1151971817017, 11.1548376083374, 11.1941051483154, 
    11.2328214645386, 11.2708168029785, 11.3079528808594, 11.3441200256348, 
    11.379243850708, 11.413275718689, 11.4461879730225, 11.4779672622681, 
    11.5086030960083, 11.5380878448486, 11.5664224624634, 11.5936222076416, 
    11.6197309494019, 11.6448259353638, 11.6690330505371, 11.6925172805786, 
    11.715461730957, 11.7380275726318, 11.7603321075439, 11.7824335098267, 
    11.8043336868286, 11.826003074646, 11.8473997116089, 11.8684978485107, 
    11.8892812728882, 11.9097518920898, 11.9299297332764, 11.9498538970947, 
    11.9695749282837, 11.9891510009766, 12.0086326599121, 12.0280637741089, 
    12.0474739074707, 12.0668773651123), label = "m2 trend component from bw filter", format.stata = "%9.0g"), 
    gdp_t = structure(c(16.1590557098389, 16.173246383667, 16.1874198913574, 
    16.2015361785889, 16.2155265808105, 16.2293128967285, 16.2428188323975, 
    16.2559795379639, 16.2687454223633, 16.281078338623, 16.2929668426514, 
    16.3044109344482, 16.3154201507568, 16.3260192871094, 16.3362445831299, 
    16.3461494445801, 16.3557968139648, 16.3652534484863, 16.3745727539062, 
    16.3838005065918, 16.3929653167725, 16.4020938873291, 16.4112186431885, 
    16.4203910827637, 16.4296894073486, 16.4392166137695, 16.4490852355957, 
    16.4593982696533, 16.4702224731445, 16.4815769195557, 16.4934349060059, 
    16.5057239532471, 16.5183372497559, 16.5311527252197, 16.5440330505371, 
    16.5568466186523, 16.5694675445557, 16.5817756652832, 16.5936641693115, 
    16.6050300598145, 16.6157875061035, 16.6258525848389, 16.6351490020752, 
    16.6436157226562, 16.651216506958, 16.6579303741455, 16.663761138916, 
    16.6687335968018, 16.672908782959, 16.6763858795166, 16.6792831420898, 
    16.6817378997803, 16.6838760375977, 16.6858062744141, 16.6876125335693, 
    16.6893463134766, 16.691032409668, 16.6926765441895, 16.6942653656006, 
    16.6957778930664, 16.6971950531006, 16.6984996795654, 16.6996784210205, 
    16.7007236480713, 16.7016372680664, 16.7024345397949, 16.7031402587891, 
    16.7037830352783, 16.7043933868408), label = "gdp trend component from bw filter", format.stata = "%9.0g"), 
    gPub_t = structure(c(13.9551515579224, 13.9652347564697, 
    13.9753246307373, 13.9854335784912, 13.9955825805664, 14.0058078765869, 
    14.0161590576172, 14.0267000198364, 14.0375080108643, 14.0486764907837, 
    14.0603094100952, 14.0725126266479, 14.0853872299194, 14.0990133285522, 
    14.1134452819824, 14.1287088394165, 14.1448097229004, 14.1617469787598, 
    14.1795215606689, 14.1981239318848, 14.2174997329712, 14.2375469207764, 
    14.2581386566162, 14.2791500091553, 14.3004627227783, 14.321967124939, 
    14.3435697555542, 14.365216255188, 14.3868970870972, 14.4086408615112, 
    14.4304866790771, 14.4524555206299, 14.474536895752, 14.4966917037964, 
    14.5188484191895, 14.5409154891968, 14.5627708435059, 14.5842790603638, 
    14.6052865982056, 14.6256370544434, 14.645167350769, 14.6637287139893, 
    14.6812047958374, 14.6975116729736, 14.7125911712646, 14.7263965606689, 
    14.7388849258423, 14.7500410079956, 14.7599010467529, 14.7685575485229, 
    14.7761507034302, 14.782844543457, 14.7888031005859, 14.7941732406616, 
    14.7990770339966, 14.8036088943481, 14.8078298568726, 14.811767578125, 
    14.8154287338257, 14.8188028335571, 14.8218755722046, 14.824631690979, 
    14.8270664215088, 14.8291921615601, 14.8310508728027, 14.832706451416, 
    14.8342294692993, 14.8356819152832, 14.8371047973633), label = "gPub trend component from bw filter", format.stata = "%9.0g")), row.names = c(NA, 
-69L), class = c("tbl_df", "tbl", "data.frame"))

Solution

I’m not entirely sure I understand your question, but I’ll take my best shot at it. From what I can gather, I think you only need one loop, and I think you would be better off making a list of dataframes. Maybe something like this:

trends_list <- list()
for(i in 1:length(dates)){
    f_date <- dates[i]
    if(i==1) prev_trend <- trends
    else prev_trend <- trends_list[dates[i-1]]
    trends_list[f_date] <- holt_filter(prev_trend, initial_date="2003 Q1", final_date=f_date, forecast_horizon=4)
    trends_list[f_date] <- trends_list[f_date] %>% rename_at(vars(-quarter), function(x) paste0(x,"t_",10+i)) %>% relocate(quarter)
}

Then, you can get whatever dataframe you want by looking at the list. That is trends_list["2010 Q4"] for the first one etc.

EDIT: I fixed the function somewhat, and I think I got the loop to work. You should be able to copy and paste the following code and it should work

trends_list <- list()
for(i in 1:length(dates)){
      f_date <- dates[i]
      if(i==1) {prev_trend <- trends
      }else {prev_trend <- trends_list[[dates[i-1]]]}
      trends_list[[f_date]] <- holt_filter(prev_trend, initial_date="2003 Q1", final_date=f_date, forecast_horizon=4)
    }

#Adding the suffixes afterwards so they do not stack on top of each other
for(i in 1:length(dates)){
      f_date <- dates[i]
      trends_list[[f_date]] <- trends_list[[f_date]] %>% 
rename_at(vars(-quarter), function(x) paste0(x,"t_",10+i)) %>% 
relocate(quarter)
      
    }

Answered By – user3124634

Answer Checked By – Dawn Plyler (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.