Forum Discussion
Linear regression in Power Query with grouping
- 4 years ago
Here's an example similar to yours that demonstrates what I was suggesting:
let Forecast = (sourceTable as table, xcol as text, ycol as text) => let range = Table.SelectRows(sourceTable, each Record.Field(_, ycol) <> 0), rowcount = Table.RowCount(range), sumx = List.Sum(Table.Column(range, xcol)), sumx2 = List.Sum(List.Transform(Table.Column(range, xcol), each Number.Power(_, 2))), sumy = List.Sum(Table.Column(range, ycol)), sumxy = List.Sum(Table.TransformRows(range, each Record.Field(_, xcol) * Record.Field(_, ycol))), avgx = List.Average(Table.Column(range, xcol)), avgy = List.Average(Table.Column(range, ycol)), Slope = ((rowcount * sumxy - sumx * sumy) / (rowcount * sumx2 - Number.Power(sumx, 2))), Intercept = avgy - Slope * avgx, Result = Table.AddColumn(sourceTable, Text.Combine({ycol, "Forecast"}), each if Record.Field(_, ycol) = 0 then Intercept + Slope * Record.Field(_, xcol) else 0, type number ) in Result, Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("ZZBRCsAgDEPv0m8/pkbHziJ+bPc/xIw4XOhHCTxC0rY1ixbsHkNNxXrYKHGioEznKQhjDiHFkSrkWXUoglgHdbEuqwsuatel3y1VCDWqaZ4CQXBJmv0tfimiVkVzcUVwUT58/am/", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [dimA = _t, dimB = _t, dimX = _t, FactY = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"dimA", Int64.Type}, {"dimB", type text}, {"dimX", Int64.Type}, {"FactY", Int64.Type}}), #"Grouped Rows" = Table.Group(#"Changed Type", {"dimA", "dimB"}, {{"SubTable", each Forecast(_, "dimX", "FactY"), type table [dimA=nullable number, dimB=nullable text, dimX=nullable number, FactY=nullable number, FactYForecast=nullable number]}}), #"Expanded SubTable" = Table.ExpandTableColumn(#"Grouped Rows", "SubTable", {"dimX", "FactY", "FactYForecast"}, {"dimX", "FactY", "FactYForecast"}) in #"Expanded SubTable"The highlighted column is the result:
That is very kind.
This is the same structure as my dataset:
| dimA | dimB | dimX | FactY |
| 1 | a | 1 | 18 |
| 1 | a | 2 | 21 |
| 1 | a | 3 | 17 |
| 1 | b | 1 | 45 |
| 1 | b | 2 | 43 |
| 1 | b | 3 | 40 |
| 2 | a | 1 | 0 |
| 2 | a | 2 | 10 |
| 2 | a | 3 | 5 |
| 2 | b | 1 | 90 |
| 2 | b | 2 | 55 |
| 2 | b | 3 | 87 |
So the problem is, I need to first select only the subset of the inputtable (I do it all in the same table just like Stephen. My inputtable is therefore the previous step in the query) where dimA has the value of dimA in that row (same for dimB) and then an additional condition on the dimX (xcol) >0.
I tried something like:
range = Table.SelectRows(sourceTable, each Record.Field(_, xcol) > 0), and Record.Field(_, dimA) = [dimA] and Record.Field(_, dimB)=[dimB]) but that doesn't work.
The calculation of the forecast should be done for each pair of dimA, dimB and all their x's and y's
Like this subset:
- Anonymous4 years agoNot applicable
Oh sorry. And there would be some rows with dimX being zero or negative (the future years) and no values for FactY