I have a table like this:
v | p |
---|---|
3 | 89 |
3.5 | 178 |
4 | 328 |
4.5 | 522 |
5 | 758 |
5.5 | 1040 |
v goes from 3 to 24 in steps of 0.5 (v = List.Numbers(3, 43, 0.5)).
p = {89, 178, 328, 522, 758, 1040, 1376, 1771, 2230, 2758, 3351, 3988, 4617, 5166, 5584, 5862, 6028, 6117, 6161, 6183, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 6192, 5956, 5832, 5708, 5584, 5460, 5336, 5212}
I want to interpolate the values for which I found a solution here. I changed the code, because I need one decimal digit.
let
Source = Excel.CurrentWorkbook(){[Name="LK"]}[Content],
//Add two columns which are the v and p columns offset by one
//It is faster to subtract this way than by adding an Index column
offset=
Table.FromColumns(
Table.ToColumns(Source)
& {List.RemoveFirstN(Source[v]) & {null}}
& {(List.RemoveFirstN(Source[p])) & {null}},
type table[v=Decimal.Type, p=Decimal.Type, sv=Decimal.Type, sp=Decimal.Type]),
// Add a column with a list of the interest rates for each data interpolated between the segments
#"p_interpol" = Table.AddColumn(offset, "p_interpol", each let
sv_val=[sv],
p_increment = ([sp]-[p])/(([sv]-[v])*10),
Lists= List.Generate(
()=>[v_val=[v],p_val=[p]],
each [v_val]< sv_val,
each [v_val=[v_val]+0.1, p_val = [p_val]+p_increment],
each [p_val])
in Lists),
// add another column with a list of days corresponding to the interest rates
#"v_interpol" = Table.AddColumn(#"p_interpol", "v_interpol", each List.Numbers([v], ([sv]-[v])/0.1, 0.1)),
//remove the last row as it will have an error
remErrRow = Table.RemoveLastN(#"v_interpol",1),
//create the new table which has the rates for every duration
LK_interpol = Table.FromColumns(
{List.Combine(remErrRow[v_interpol]),List.Combine(remErrRow[p_interpol])},
type table[v=Decimal.Type, p=Decimal.Type])
in
LK_interpol
As Output I get this:
v | p |
---|---|
3 | 89 |
3.1 | 106.8 |
3.2 | 124.6 |
3.3 | 142.4 |
3.4 | 160.2 |
3.5 | 178 |
3.6 | 208 |
3.7 | 238 |
3.8 | 268 |
3.9 | 298 |
4 | 328 |
4.1 | 366.8 |
4.2 | 405.6 |
4.3 | 444.4 |
4.4 | 483.2 |
4.5 | 522 |
4.6 | 522 |
4.7 | 569.2 |
The interpolation works until v = 4. It seems like the condition in the List.Generate function doesn't work anymore when v = 4, because the generated list contains six instead of five elements. This leads to doubled values (in the example output 522 for v = 4.5). The same problem occurs for the following rows until v = 16. From v = 16 on the interpolation works again.
I also tested what happens if I add rows before v = 3 or if I change the values of p. The result stays the same: List.Generate generates me a list with six elements if v >= 4 and v < 16, otherwise the generated list has five elements.
What could be the reason? Maybe something with the datatype?
Seems like it should work, not quite sure why it doesnt (perhaps rounding in smallest decimal point) but you can fix it with
#"p_interpol" = Table.AddColumn(offset, "p_interpol", each let
sv_val=[sv],
p_increment = ([sp]-[p])/(([sv]-[v])*10),
Lists= List.Generate(
()=>[v_val=[v],p_val=[p]],
each [v_val]< sv_val,
each [v_val=[v_val]+0.1, p_val = [p_val]+p_increment],
each [p_val]),
Clip=List.FirstN(Lists,([sv]-[v])*10)
in Clip),