Forum Discussion
How to calculate the difference between two points that do not overlap
- 1 year ago
Hi Anonymous ,
To calculate the difference between non-overlapping top and bot elevation points, you need to interpolate one or both datasets so that they align on the same x-axis. Since the x-values are not matched across the two elevation types, you can’t simply subtract [top] - [bot]. Instead, in Power Query, start by extracting a master list of unique x-values across both top and bot data using:
CombinedX = List.Distinct(YourTable[x-axis])Then split your original table into two separate queries—one for top and one for bot—like this:
TopTable = Table.SelectRows(YourTable, each [Point Type] = "top") BotTable = Table.SelectRows(YourTable, each [Point Type] = "bot")Now you need to reindex and interpolate each table to fill in missing x-axis values. To do this, perform a left join from the CombinedX list to each of the top and bot tables. This will give you rows with null elevations where values are missing. Then sort the joined table by x, add an index, and for rows with missing elevations, identify the previous and next known values and interpolate using this formula:
Interpolated = y1 + (x - x1) * ((y2 - y1) / (x2 - x1))Where x is the missing point, and (x1, y1) and (x2, y2) are the bounding known data points. You can extract these by grouping and adding custom columns with List.FirstN and List.Skip operations or using buffer + index tricks. Once both top and bot tables are interpolated with the same set of x-values, merge them together on x and compute the difference:
Delta = [Top Elevation] - [Bot Elevation]This will give you the vertical gap between the two elevation lines at every point, even when the original data did not overlap. If you're dealing with millions of rows, do this logic inside Power Query rather than DAX to avoid performance bottlenecks.
Best regards,
Hi Anonymous,
I wanted to check if you had the opportunity to review the information provided. Please feel free to contact us if you have any further questions. If my response has addressed your query, please accept it as a solution so that other community members can find it easily.
Thank you.
Yes I did! I have millions of rows so I ran it via Power Query, and it definately worked. Slightly different variant for the dataset I have.
The code I used:
let
// 1. Load your data
Source = #"Elevation Data",
// 2. Separate top (top) and bot (bot) points
topPoints = Table.SelectRows(Source, each [Elevation Type] = "top"),
botPoints = Table.SelectRows(Source, each [Elevation Type] = "bot"),
// 3. Sort bot points by X_AXIS_M (ascending)
botPointsSorted = Table.Sort(botPoints, {{"X_AXIS_M", Order.Ascending}}),
// 4. Function to interpolate bot elevation at a given X_AXIS_M
Interpolatebot = (x as number) as nullable number =>
let
// Find all bot points with X_AXIS_M less than or equal to x
LowerRows = Table.SelectRows(botPointsSorted, each [X_AXIS_M] <= x),
// Find all bot points with X_AXIS_M greater than x
UpperRows = Table.SelectRows(botPointsSorted, each [X_AXIS_M] > x),
// Get the last lower point
Lower = if Table.RowCount(LowerRows) > 0 then LowerRows{Table.RowCount(LowerRows)-1} else null,
// Get the first upper point
Upper = if Table.RowCount(UpperRows) > 0 then UpperRows{0} else null,
// If both points exist, interpolate
Interpolated = if Lower <> null and Upper <> null and Lower[X_AXIS_M] <> Upper[X_AXIS_M]
then
Lower[elevation] + (x - Lower[X_AXIS_M]) * (Upper[elevation] - Lower[elevation]) / (Upper[X_AXIS_M] - Lower[X_AXIS_M])
else null
in
Interpolated,
// 5. Add interpolated bot elevation to each top point
topWithbot = Table.AddColumn(
topPoints,
"Interpolated bot",
each Interpolatebot([X_AXIS_M]),
type number
),
// 6. Calculate Delta (top - Interpolated bot)
Result = Table.AddColumn(
topWithbot,
"Delta",
each [elevation] - [Interpolated bot],
type number
),
#"Filtered Rows" = Table.SelectRows(Result, each [Interpolated bot] <> null and [Interpolated bot] <> "")
in
#"Filtered Rows"