Transforming Actual vs Budget Data in Excel using Power Query M
Description
This project focuses on transforming a given dataset that includes actual and budget values for various accounts. You'll learn how to use Power Query M in Excel to reshape the data into a more analyzable format with columns for Month, Year, Account, Budget Amount, and Actual Amount. By the end of this project, you will have a practical understanding of data transformation techniques in Power Query M.
The original prompt:
I have the following Data Set. It is actual vs budget. I want to transform this data set into the following columns using power query M code: Month, Year, Account, Budget Amount, Actual Amount. Row 2 contains labels for Actuals or Budget per column, row 3 contains Month-Year, column contains a list of accounts. Provide for me the list of steps needed for the wanted outcome given this input:
Trim Column3 Column4 Column5 Column6 Actuals 2024 Budget 3x9 $90M Actuals 2024 Budget 3x9 $90M Accounts Jan-2024 Jan-2024 Feb-2024 Feb-2024 6020 - Indirect labor - salary and wage 7076.92 7076.92 6461.53 6461.53 6031 - Paid Time Off (PTO) 6040 - Bonus Pay 6070 - Fringe - Group Medical & Dental 793 793 793 793 6071 - Fringe - HSA Employer Match 500 500 6073 - Fringe - Workers' Compensation 5 5 5 5 6080 - Payroll Taxes 600.86 600.86 495.02 495.02 6200 - Travel - Airfare, Train or Bus 6205 - Travel - Personal Meals 6210 - Travel - Business Meals & Entertainment 6215 - Travel - Lodging 299 299 6220 - Travel - Car Expense (Rental, Fuel, Taxi, Parking) 6225 - Travel - Mileage 298.7 298.7 -50 -50 6375 - Digital Product Development 1200.65 1200.65 1499.65 1499.65 6900 - Software Agreement, License, Renewal 66018.34 66018.34 80553.94 80553.94 6910 - Computer Hardware 6463.48 6463.48 11788.24 11788.24 6920 - Platform Agreements - DTC 20440.26 20440.26 20171.62 20171.62 7130 - Equipment Lease 5699.57 5699.57 1068.73 1068.73 7300 - Telephone & Company Internet 12128.09 12128.09 12081.95 12081.95 7310 - Cell Phone 450.21 450.21 462.24 462.24 7330 - Employee Internet 215 215 195 195 7525 - Outside Services 17280.31 17280.31 17139.4 17139.4 7535 - Certifications 811.13 811.13 811.13 811.13 7700 - Allocation Support -24262 -24262 -24523 -24523
Understanding the Initial Dataset
Introduction
This section will show you how to understand and transform your actual vs. budget data using Power Query M language in Excel. You will learn to import, clean, and transform your dataset, setting the foundation for better data insights and analysis.
Instructions
Step 1: Importing Data
- Open Excel and navigate to the 'Data' tab.
- Click on 'Get Data' > 'From File' > 'From Workbook'.
- Select the Excel file containing your actual vs. budget data.
- Choose the specific sheet or range containing the data and click 'Load' or 'Transform Data' for more customization.
Step 2: Inspecting the Dataset
Once the data is loaded into Power Query Editor, inspect its structure:
// View the first few rows of the dataset
let
Source = Excel.CurrentWorkbook(){[Name="YourTableName"]}[Content],
FirstRows = Table.FirstN(Source, 10)
in
FirstRows
This script will show you the first 10 rows of your data to get a sense of what it looks like.
Step 3: Data Cleansing
Ensure columns have appropriate data types and handle any missing values:
let
Source = Excel.CurrentWorkbook(){[Name="YourTableName"]}[Content],
// Convert data types
ChangedType = Table.TransformColumnTypes(Source, {
{"Date", type date},
{"Actual", type number},
{"Budget", type number},
{"Category", type text}
}),
// Remove rows with missing values
RemovedRows = Table.RemoveRowsWithErrors(ChangedType)
in
RemovedRows
Step 4: Adding Calculated Columns
Add a calculated column to see the variance between actual and budget values:
let
Source = Excel.CurrentWorkbook(){[Name="YourTableName"]}[Content],
ChangedType = Table.TransformColumnTypes(Source, {
{"Date", type date},
{"Actual", type number},
{"Budget", type number},
{"Category", type text}
}),
RemovedRows = Table.RemoveRowsWithErrors(ChangedType),
// Add a new column to calculate variance
AddedCustom = Table.AddColumn(RemovedRows, "Variance", each [Actual] - [Budget], type number)
in
AddedCustom
Step 5: Grouping Data
Group data by Category to get summarised insights:
let
Source = Excel.CurrentWorkbook(){[Name="YourTableName"]}[Content],
ChangedType = Table.TransformColumnTypes(Source, {
{"Date", type date},
{"Actual", type number},
{"Budget", type number},
{"Category", type text}
}),
RemovedRows = Table.RemoveRowsWithErrors(ChangedType),
AddedCustom = Table.AddColumn(RemovedRows, "Variance", each [Actual] - [Budget], type number),
// Group by Category
GroupedData = Table.Group(AddedCustom, {"Category"}, {
{"Total Actual", each List.Sum([Actual]), type number},
{"Total Budget", each List.Sum([Budget]), type number},
{"Total Variance", each List.Sum([Variance]), type number}
})
in
GroupedData
Step 6: Loading Transformed Data Back into Excel
Once you've done the necessary transformations, load the data back into Excel:
- Click on 'Close & Load' in the Power Query Editor.
- Select 'Close & Load To' to customize how you want the data loaded into Excel (e.g., to a table or pivot table).
Conclusion
You have successfully transformed and analyzed your actual vs. budget data in Excel using Power Query M language. This foundational step sets up a robust structure for further data insights and analysis.
Loading and Shaping Data in Power Query
Loading Data into Power Query
Load Actual Data Table
let Source = Excel.Workbook(File.Contents("C:\Path\To\ActualData.xlsx"), null, true), Actuals_Sheet = Source{[Name="Actuals"]}[Content], ChangedType = Table.TransformColumnTypes(Actuals_Sheet,{{"Date", type date}, {"Amount", type number}, {"Category", type text}}) in ChangedType
Load Budget Data Table
let Source = Excel.Workbook(File.Contents("C:\Path\To\BudgetData.xlsx"), null, true), Budget_Sheet = Source{[Name="Budget"]}[Content], ChangedType = Table.TransformColumnTypes(Budget_Sheet,{{"Date", type date}, {"Amount", type number}, {"Category", type text}}) in ChangedType
Shaping and Transforming Data
Removing Unnecessary Columns
let RemovedColumns = Table.RemoveColumns(ChangedType, {"UnnecessaryColumn1", "UnnecessaryColumn2"}) in RemovedColumns
Filtering Data
let FilteredRows = Table.SelectRows(RemovedColumns, each ([Date] >= #date(2023, 1, 1) and [Date] <= #date(2023, 12, 31))) in FilteredRows
Pivoting Data (if needed)
let PivotedColumn = Table.Pivot(RemovedColumns, List.Distinct(RemovedColumns[Category]), "Category", "Amount", List.Sum) in PivotedColumn
Renaming Columns
let RenamedColumns = Table.RenameColumns(RemovedColumns, {{"OldColumnName", "NewColumnName"}}) in RenamedColumns
Merging Data: Actual vs Budget
let MergedTables = Table.NestedJoin(ActualsTable, {"Date", "Category"}, BudgetTable, {"Date", "Category"}, "BudgetData", JoinKind.LeftOuter), ExpandedBudget = Table.ExpandTableColumn(MergedTables, "BudgetData", {"Amount"}, {"BudgetAmount"}) in ExpandedBudget
Calculating Variance
let AddedVariance = Table.AddColumn(ExpandedBudget, "Variance", each [Amount] - [BudgetAmount], type number) in AddedVariance
Final Steps
- Close & Load After performing all the transformations, click on the 'Close & Load' option in Power Query to load the transformed data back into Excel for further analysis.
By following these steps, you can effectively load and shape your Actual vs Budget data in Excel using Power Query M language, enabling more insightful data analysis and visualization.
Transforming Columns and Rows in Power Query M Language for Actual vs Budget Data
Below you will find the practical implementation for transforming columns and rows in Power Query M Language for an Excel data project comparing actual vs budget data.
Example Data
Assume you have the following initial dataset loaded in Power Query:
Date | Category | Actual | Budget |
---|---|---|---|
2023-01-01 | Sales | 2000 | 1800 |
2023-01-01 | Expenses | 1500 | 1400 |
2023-02-01 | Sales | 2200 | 1900 |
2023-02-01 | Expenses | 1600 | 1500 |
Transforming Columns and Rows
Step 1: Unpivot the Actual and Budget Columns
To analyze the difference between actual and budget values, you may want to unpivot these columns.
let
Source = YourSourceHere,
UnpivotedColumns = Table.UnpivotOtherColumns(Source, {"Date", "Category"}, "Attribute", "Value")
in
UnpivotedColumns
This will transform your data to:
Date | Category | Attribute | Value |
---|---|---|---|
2023-01-01 | Sales | Actual | 2000 |
2023-01-01 | Sales | Budget | 1800 |
2023-01-01 | Expenses | Actual | 1500 |
2023-01-01 | Expenses | Budget | 1400 |
2023-02-01 | Sales | Actual | 2200 |
2023-02-01 | Sales | Budget | 1900 |
2023-02-01 | Expenses | Actual | 1600 |
2023-02-01 | Expenses | Budget | 1500 |
Step 2: Pivoting More Granular Rows into Columns
If you want to have a table where each row is a monthly summary for each category, with actuals and budget side-by-side:
let
Source = YourSourceHere,
UnpivotedColumns = Table.UnpivotOtherColumns(Source, {"Date", "Category"}, "Attribute", "Value"),
PivotedColumns = Table.Pivot(UnpivotedColumns, List.Distinct(UnpivotedColumns[Attribute]), "Attribute", "Value")
in
PivotedColumns
This will transform your data to:
Date | Category | Actual | Budget |
---|---|---|---|
2023-01-01 | Sales | 2000 | 1800 |
2023-01-01 | Expenses | 1500 | 1400 |
2023-02-01 | Sales | 2200 | 1900 |
2023-02-01 | Expenses | 1600 | 1500 |
Step 3: Calculating Variances
To calculate the variance between actuals and budgets:
let
Source = YourSourceHere,
UnpivotedColumns = Table.UnpivotOtherColumns(Source, {"Date", "Category"}, "Attribute", "Value"),
PivotedColumns = Table.Pivot(UnpivotedColumns, List.Distinct(UnpivotedColumns[Attribute]), "Attribute", "Value"),
AddVarianceColumn = Table.AddColumn(PivotedColumns, "Variance", each [Actual] - [Budget])
in
AddVarianceColumn
This adds a "Variance" column to your dataset:
Date | Category | Actual | Budget | Variance |
---|---|---|---|---|
2023-01-01 | Sales | 2000 | 1800 | 200 |
2023-01-01 | Expenses | 1500 | 1400 | 100 |
2023-02-01 | Sales | 2200 | 1900 | 300 |
2023-02-01 | Expenses | 1600 | 1500 | 100 |
Conclusion
By following the above steps, you have successfully transformed your data to allow for better insights and analysis. The transformations include unpivoting, pivoting, and calculating variance—all essential for a thorough understanding of actual vs budget data in Excel using Power Query M Language.
Implementing M Code for Data Transformation
In this part, we will focus on transforming and shaping the actual vs budget data in Power Query using the M language. The objective here is to demonstrate how to perform typical transformations such as filtering, merging, and aggregating data to provide meaningful insights.
Start with Initial Transformations
Filtering Data
We want to filter the data to show only entries from the current financial year.
let
Source = Excel.CurrentWorkbook(){[Name="ActualBudgetData"]}[Content],
FilteredRows = Table.SelectRows(Source, each [Year] = Date.Year(DateTime.LocalNow()))
in
FilteredRows
Renaming Columns
Standardize column names for better readability.
let
RenamedColumns = Table.RenameColumns(FilteredRows, {{"Actual Amount", "Actual"}, {"Budget Amount", "Budget"}})
in
RenamedColumns
Merging Data
Assuming that ActualData
and BudgetData
are in different tables, we can merge them.
let
ActualData = Excel.CurrentWorkbook(){[Name="ActualData"]}[Content],
BudgetData = Excel.CurrentWorkbook(){[Name="BudgetData"]}[Content],
MergedTable = Table.NestedJoin(ActualData, {"ID"}, BudgetData, {"ID"}, "BudgetTable", JoinKind.Inner),
ExpandedTable = Table.ExpandTableColumn(MergedTable, "BudgetTable", {"Budget"}, {"Budget"})
in
ExpandedTable
Creating Custom Columns
Calculate the variance between actual and budget amounts.
let
CustomColumn = Table.AddColumn(ExpandedTable, "Variance", each [Actual] - [Budget])
in
CustomColumn
Aggregating Data
Group by necessary categories and summarize actual and budget data.
let
GroupedTable = Table.Group(CustomColumn, {"Category"}, {{"TotalActual", each List.Sum([Actual]), type number}, {"TotalBudget", each List.Sum([Budget]), type number}})
in
GroupedTable
Adding More Insights
Calculate percentage variance:
let
PercentVariance = Table.AddColumn(GroupedTable, "PercentVariance", each ([TotalActual] - [TotalBudget]) / [TotalBudget] * 100, type number)
in
PercentVariance
Final Result
Combine all steps in a final query:
let
Source = Excel.CurrentWorkbook(){[Name="ActualBudgetData"]}[Content],
FilteredRows = Table.SelectRows(Source, each [Year] = Date.Year(DateTime.LocalNow())),
RenamedColumns = Table.RenameColumns(FilteredRows, {{"Actual Amount", "Actual"}, {"Budget Amount", "Budget"}}),
ActualData = Excel.CurrentWorkbook(){[Name="ActualData"]}[Content],
BudgetData = Excel.CurrentWorkbook(){[Name="BudgetData"]}[Content],
MergedTable = Table.NestedJoin(ActualData, {"ID"}, BudgetData, {"ID"}, "BudgetTable", JoinKind.Inner),
ExpandedTable = Table.ExpandTableColumn(MergedTable, "BudgetTable", {"Budget"}, {"Budget"}),
CustomColumn = Table.AddColumn(ExpandedTable, "Variance", each [Actual] - [Budget]),
GroupedTable = Table.Group(CustomColumn, {"Category"}, {{"TotalActual", each List.Sum([Actual]), type number}, {"TotalBudget", each List.Sum([Budget]), type number}}),
PercentVariance = Table.AddColumn(GroupedTable, "PercentVariance", each ([TotalActual] - [TotalBudget]) / [TotalBudget] * 100, type number)
in
PercentVariance
Conclusion
This implementation leverages Power Query's M language to transform actual vs budget data effectively. The steps include filtering by year, renaming columns, merging tables, calculating variances, grouping data, and adding insightful custom columns. Apply these transformations to streamline your data analysis workflows in Excel.
Validating and Utilizing Transformed Data
In this section, we will validate and utilize the transformed data within Power Query to ensure the accuracy and usability of the transformed Actual vs Budget data. This guide assumes transformations have already been applied and focuses on confirming their correctness and preparing the transformed data for further analysis.
Steps to Validate and Utilize Transformed Data
Step 1: Validate Transformed Data
Check for Data Integrity:
- Ensure that no data values have been lost or altered unexpectedly during the transformation process.
- Use the
Table.RowCount
function to verify that the number of rows matches expectations.
let Source = /* Your Data Source */, TransformedData = /* Your Transformation Steps */, RowCount = Table.RowCount(TransformedData) in RowCount
Confirm Data Types:
- Explicitly specify data types for each column to prevent any issues during data analysis.
let Source = /* Your Data Source */, TransformedData = /* Your Transformation Steps */, TypedData = Table.TransformColumnTypes(TransformedData, { {"Actual", type number}, {"Budget", type number}, {"Date", type date} }) in TypedData
Verify Data Consistency:
- Ensure that transformed data follows the expected format for analysis.
- Use Power Query’s built-in profiling tools to examine column distributions and identify any anomalies (like missing values).
Step 2: Utilizing the Transformed Data
Create Calculated Columns:
- Add new columns to derive meaningful insights from the transformed data, such as calculating variance between actual and budget values.
let Source = /* Your Data Source */, TransformedData = /* Your Transformation Steps */, TypedData = Table.TransformColumnTypes(TransformedData, { {"Actual", type number}, {"Budget", type number}, {"Date", type date} }), AddVarianceColumn = Table.AddColumn(TypedData, "Variance", each [Actual] - [Budget], type number) in AddVarianceColumn
Aggregate Data for Analysis:
- Group data by relevant categories (e.g., by month or department) to summarize Actual vs Budget differences.
let Source = /* Your Data Source */, TransformedData = /* Your Transformation Steps */, TypedData = Table.TransformColumnTypes(TransformedData, { {"Actual", type number}, {"Budget", type number}, {"Date", type date} }), AddVarianceColumn = Table.AddColumn(TypedData, "Variance", each [Actual] - [Budget], type number), GroupedData = Table.Group(AddVarianceColumn, {"Date"}, { {"TotalActual", each List.Sum([Actual]), type number}, {"TotalBudget", each List.Sum([Budget]), type number}, {"TotalVariance", each List.Sum([Variance]), type number} }) in GroupedData
Prepare Data for Visualization:
- Ensure data is in a clean, aggregated state, ready to be loaded into Excel or other visualization tools.
let Source = /* Your Data Source */, TransformedData = /* Your Transformation Steps */, TypedData = Table.TransformColumnTypes(TransformedData, { {"Actual", type number}, {"Budget", type number}, {"Date", type date} }), AddVarianceColumn = Table.AddColumn(TypedData, "Variance", each [Actual] - [Budget], type number), GroupedData = Table.Group(AddVarianceColumn, {"Date"}, { {"TotalActual", each List.Sum([Actual]), type number}, {"TotalBudget", each List.Sum([Budget]), type number}, {"TotalVariance", each List.Sum([Variance]), type number} }), CleanedData = Table.SelectColumns(GroupedData, {"Date", "TotalActual", "TotalBudget", "TotalVariance"}) in CleanedData
Outcome
Following these steps will help you validate the transformed Actual vs Budget data and prepare it for further analysis. By adding calculated columns, aggregating data, and ensuring data integrity and consistency, you can gain more accurate and actionable insights from your analysis.