# How do I transform my results? List-manipulation? Interpolation?

I have the data

{{0, 10, 10}, {0.01829, 12, 10}, {0.0523236, 11, 10}, {0.0616182, 11, 9},
{0.0860192, 10, 9}, {0.37603, 12, 9}, {0.405224, 11, 9}, {0.415151, 11, 8},
{0.453143, 13, 8}, {0.481562, 12, 8}, {0.482285, 11, 8}, {0.490412, 10, 8},
{0.492742, 10, 7}, {0.558841, 9, 7}, {0.602336, 8, 7}, {0.683204, 8, 6},
{0.738865, 9, 7}, {0.766657, 9, 9}, {0.780627, 9, 8}, {0.900705, 9, 10},
{0.905607, 9, 9}, {0.926086, 9, 8}, {1.00437, 9, 7}, {1.01303, 11, 7},
{1.06747, 10, 7}, {1.07523, 9, 7}, {1.33235, 8, 7}, {1.51981, 7, 8},
{1.61516, 6, 8}, {1.66955, 6, 7}, {1.95405, 5, 7}, {2.04023, 5, 6},
{2.04605, 5, 5}, {2.23846, 5, 4}, {2.25056, 4, 4}, {2.27559, 3, 4},
{2.5348, 2, 5}, {2.55095, 2, 6}, {2.71852, 2, 5}, {2.95299, 4, 5},
{3.23626, 6, 5}}


which represents {time, amount1, amount2}. Changes to each amount only happens at the times stated in the results.

How do I transform my data so it tells me the two amounts for discrete moments in time?

For example, for steps of 0.5, the data would be the following

{0, 10, 10}, {0.5, 10, 7}, {1.0, 9, 8}, {1.5, 8, 7},
{2.0, 5, 7}, {2.5, 3, 4}, {3.0, 4, 5}


For example, for steps of 1, the data would be the following

{0, 10, 10}, {1, 9, 8}, {2, 5, 7}, {3, 4, 5}

• Maybe you want to try Nearest[]. Mar 24, 2018 at 16:00

Can use TimeSeries and TimeSeriesResample:

pts = Dataset[{{0, 10, 10},...,{3.23626, 6, 5}}];


Wrap cols 2 and 3 in a List and then TimeSeries

ts = pts[All,{1,{2,3}}][TimeSeries];


Resample:

ts // TimeSeriesResample[#, 0.5] & // #["Path"] &


{{0., {10., 10.}}, {0.5, {9.8902, 7.}}, {1., {9., 7.05582}}, {1.5, {7.10568, 7.89432}}, {2., {5., 6.46681}}, {2.5, {2.13425, 4.86575}}, {3., {4.33191, 5.}}}

Note, from ref page:

"By default, values at intermediate times are computed using first-order interpolation"

Other interpolation methods are available, eg:

ts // TimeSeriesResample[#, 0.5,
ResamplingMethod -> {"Interpolation",
InterpolationOrder -> 0}] & // #["Path"] &


{{0., {10, 10}}, {0.5, {10, 7}}, {1., {9, 8}}, {1.5, {8, 7}}, {2., {5, 7}}, {2.5, {3, 4}}, {3., {4, 5}}}

• This method will not give me integers values will it? @alancalvitti Mar 24, 2018 at 16:09
• @Mlo27, it does if the input values are integers and InterpolationOrder->0 is chosen - see last line in my answer. (Obviously the time values you wanted are resampled at 0.5 so are not going to be integers). Mar 24, 2018 at 16:19
• The time values do not have the be integers. I just need the output to always be integers. Will this method allow that? @alancalvitti Mar 24, 2018 at 16:24
• @Mlo27, yes, as I said, read the last line of output. You can use Flatten to get the same verbatim format as in your Q, but that will interfere with any subsequent TimeSeries operations. Mar 24, 2018 at 16:27
• Sorry didn’t see that last bit. Thanks for the advice, I’ll give it a try later on :D Mar 24, 2018 at 16:33

You can use a modification of StepFunction from my answer to How can the behavior of InterpolationOrder->0 be controlled?:

StepFunction[data_] := Module[{sdata, nf}, sdata=Sort@data;
nf = Nearest[sdata[[All,1]] -> "Index"];
StepFunction[nf, sdata[[All,1]], sdata[[All, {2,3}]], {-1,0}]
]

StepFunction[nf_NearestFunction, x_, y_, clip_][pt_List] := With[
{near = nf[pt][[All,1]]},
Join[
List/@pt,
y[[Clip[near + Clip[Sign[Subtract[pt, x[[near]]]], clip], {1, Length[x]}]]],
2
]
]
StepFunction[nf_NearestFunction, x_, y_, clip_][pt_] := With[
{near = First@nf[pt]},
Prepend[
y[[Clip[near + Clip[Sign[Subtract[pt, x[[near]]]], clip], {1, Length[x]}]]],
pt
]
]


sf = StepFunction[{
{0,10,10},{0.01829,12,10},{0.0523236,11,10},{0.0616182,11,9},{0.0860192,10,9},
{0.37603,12,9},{0.405224,11,9},{0.415151,11,8},{0.453143,13,8},{0.481562,12,8},
{0.482285,11,8},{0.490412,10,8},{0.492742,10,7},{0.558841,9,7},{0.602336,8,7},
{0.683204,8,6},{0.738865,9,7},{0.766657,9,9},{0.780627,9,8},{0.900705,9,10},
{0.905607,9,9},{0.926086,9,8},{1.00437,9,7},{1.01303,11,7},{1.06747,10,7},
{1.07523,9,7},{1.33235,8,7},{1.51981,7,8},{1.61516,6,8},{1.66955,6,7},{1.95405,5,7},
{2.04023,5,6},{2.04605,5,5},{2.23846,5,4},{2.25056,4,4},{2.27559,3,4},{2.5348,2,5},
{2.55095,2,6},{2.71852,2,5},{2.95299,4,5},{3.23626,6,5}
}];


Then:

sf[Range[0, 3, .5]]
sf[Range[0, 3]]


{{0., 10, 10}, {0.5, 10, 7}, {1., 9, 8}, {1.5, 8, 7}, {2., 5, 7}, {2.5, 3, 4}, {3., 4, 5}}

{{0, 10, 10}, {1, 9, 8}, {2, 5, 7}, {3, 4, 5}}

• This method isn't producing an output @Carl Woll Mar 24, 2018 at 18:37
• @Mlo27 If you are using M10 or earlier, replace "Index" with Automatic. Mar 24, 2018 at 19:35
• @CarlWoll How can I modify your code for this question. Suggested method is very slow for large data. mathematica.stackexchange.com/questions/172298/… May 1, 2018 at 23:19