Smoothed mean on +/- 1 week from target

I'm trying to do a smoothed mean on weeks, but need to do it on the +/- 1 week before and after the target week, and the overlap from week 52/53 to week 1 is giving me a few issues. I can hardcode it with a for loop and a few if statements and make it work, but I'm convinced there is a more elegant solution.

I'm looking for a data.frame output with two columns, weeks ranging 1:53 and where value is a smoothed mean. For week 1 it should average week 53, 1 and 2. For week 53 the average should consist of the values in week 52, 53 and 1. It would be great if it could be used as a summary function after a dplyr::group_by pipe.

I have generated a few years of weekly data:

week <- c(1:53, 1:52, 1:52)

tibble(week = week,
             value = rnorm(n = length(week)))

Edit: I'm looking for a solution that summarise into distinct weeks, but where the mean also includes the neighboring weeks.

I like the slider package for sliding window things.

library(tidyverse)
library(slider)

example_df <- tibble(week =  c(1:53, 1:52, 1:52),
       value = rnorm(n = length(week))) 

example_df$mean <- example_df %>% 
                    slide_dbl(~mean(.x$value),
                              .before=1,.after = 1)

Thanks for looking at this problem!

This doesn't summarise the data.frame to distinct weeks but is "sliding" over the whole data. I'm looking for a solution that summarise into distinct weeks, but where the mean also includes the neighboring weeks.

The description might be a bit confusing. I'll change it a bit.

I wouldn't swear that I understand your goal, but I think you can summarise by week the smoothed means and make a composite mean (of means)
assuming you adopt my proposal, continue it with:

example_df %>% 
        group_by(week) %>% 
        summarise(mean=mean(mean))

I'm looking for a solution like below, but where I can easily change the "window" of weeks.

library(tidyverse)
example_df <- tibble(week =  c(1:53, 1:52, 1:52),
                     value = rnorm(n = length(week))) 


get_weeks <- function(week){
  
  if(week == 1){
    week <- c(53, 1, 2)
  } else if(week == 53){
    week <- c(52, 53, 1)
  } else {
    week <- c(week - 1, week, week + 1)
  }
  week
}

tibble(week = 1:53,
       value = sapply(1:53,
       function(x){
         weeks_to_keep <- get_weeks(x)
         
         example_df %>%
           filter(week %in% weeks_to_keep) %>%
           pull(value) %>%
           mean(.)
       }))

to change the window of my proposal would involve changing the numbers in : .before=1,.after = 1

Yes, but my example data is overly simplified as I have a few hundred thousand observations in each week per year, so running the slider like that is not possible. I think I'll try to generalise the get_weeks function to be more like the slider function with "before" and "after" params.

Thanks for trying to help me though. It's much appriciated.