Home » excel » excel – Moving average excluding weekends and holidays

excel – Moving average excluding weekends and holidays

Posted by: admin May 14, 2020 Leave a comment

Questions:

I have a table within PowerPivot currently that tracks a count of customers through our sales pipeline. From (by sales location) first interaction to charged sale. So far, I’ve creates a moving 5-day average that averages each task. Below is the DAX formula I’ve created thus far and an example table.

=
CALCULATE (
    SUM ( [Daily Count] ),
    DATESINPERIOD ( Table1[Date], LASTDATE ( Table1[Date] ), -7, DAY ),
    ALLEXCEPT ( Table1, Table1[Sales Location], Table1[Group] )
)
    / 5

enter image description here

Where I’m struggling is being able to come up with a way to exclude weekends and company observed holidays. Additionally, if a holiday falls on a weekday I would like to remove that from the average and go back an additional day (to smooth the trend).

For example, on 11/26/18 (the Monday after Thanksgiving and Black Friday) I would like to average the five business days previous (11/26/18, 11/21-11/19, and 11/16). In the example above, the moving total and average for the previous 5 days should be Intake = 41 (total) 8.2 (average), Appointment = 30 (total) 6 (average), and Sale = 13 (total) and 2.6 (average).

Based on the formula currently, each of these numbers is inaccurate. Is there an easy way to exclude these days?

Side note: I’ve created an ancillary table with all holidays that is related to the sales data that I have.

Thank you for the help!

How to&Answers:

For this, I’d recommend using a calendar table related to Table1 on the Date column that also has a column IsWorkday with 1 if that day is a workday and 0 otherwise.

Once you have that set up, you can write a measure like this:

Moving Avg =
VAR Last5Workdays =
    SELECTCOLUMNS (
        TOPN (
            5,
            FILTER (
                DateTable,
                DateTable[Date] <= EARLIER ( Table1[Date] )
                    && DateTable[IsWorkday] = 1
            ),
            DateTable[Date], DESC
        ),
        "Workday", DateTable[Date]
    )
RETURN
    CALCULATE (
        SUM ( Table1[Daily Count] ),
        Table1[Date] IN Last5Workdays
        ALLEXCEPT ( Table1, Table1[Sales Location], Table1[Group] ),
    )
        / 5

The TOPN function here returns the top 5 rows of the DateTable where each row must be a workday that is less than or equal to the date in your current Table1 row (the EARLIER function refers to the earlier row context that defines the current row).

I then use SELECTCOLUMNS to turn this table into a list by selecting a single column (which I’ve named Workday). From there, it’s basically your measure with the date filter changed a bit.

Answer:

@alexisolson Thank you for the response here. I was actually able to figure this out over the weekend but forgot to close out the thread (sorry about that! Appreciate your help either way). But I did something fairly similar to what you mentioned above.

I created a date table (CorpCalendar) that was only inclusive of working days. Then I created an index column within the CorpCalendar table to give each row a unique number in ascending order. From there, I linked the CorpCalendar table to my SalesData table by related dates and used the LOOKUPVALUE function to bring the index value over from the CorpCalendar table to the SalesData table. In a separate column I subtracted 4 from the date index value to get an index adjustment column (for a range of five days from the actual date index and the adjustment…if that makes sense). I then added an additional LOOKUPVALUE helper column to match the adjusted date index column to the appropriate working day.Lastly, I then used the following function to get the 5 day rolling average.

=CALCULATE(sum(Combined[Daily Count]),DATESBETWEEN(Combined[Date - Adjusted],Combined[Date - Adjusted (-5)],Combined[Date - Adjusted]),ALLEXCEPT(Combined,Combined[Group]))/5

This is probably more convoluted than necessary, however, it got me to the answer I was looking for. Let me know if this makes sense and if you have any suggestions for future scenarios like this.

Thanks again!