How to use Interpolation to fill in missing data

I have a bit of data that looks like this:

data = {79., 79.1, 78.3, 78.6, 79., 77.2, 79.3, 79.3, "", "", 79.3, 76.6, \
79.3, 79.8, 78.4, 79., 78.4, 78.4, 79.4, 79.5, 79.4, 79.3, 79.2, \
79.2, 79.3, 79.6, "", 79.2, 79.3, 79., 79.1, 79.2}


I'm looking to do Linear Interpolation to fill in the missing data. The Interpolation functions with InterpolationOrder->1 seems to be just what I am looking for. But I can't figure out how to feed the data to the Interpolation function in order to get a a sensible result.

You have to provide the values of independent variable. Assuming that the points correspond to equidistant values of an independent variable, you can do this, for example:

int =
Interpolation[
Select[Transpose[{Range[Length[data]], data}], NumericQ[Last[#]] &],
InterpolationOrder -> 1
]


Of course, you may wish to scale the independent variable here in some way.

• Works perfectly, thank you! Looking at the solution it bugs me that I was soo close but couldn't quite put two and two together to get it right. – Mr Alpha May 1 '12 at 13:51
• @MrAlpha Glad I could help! Thanks for the accept. – Leonid Shifrin May 1 '12 at 14:19

In versions 9+, you can also use the option MissingDataMethod after processing your data into a TemporalData object:

ClearAll[iF]
iF[d_, o_:1] := TemporalData[Replace[d, Except[_?NumericQ]:>Missing[], 1], Automatic,
MissingDataMethod -> {"Interpolation", InterpolationOrder -> o}]["States"]


Examples:

data = {79., 79.1, 78.3, 78.6, 79., 77.2, 79.3, 79.3, "", "", 79.3, 76.6,
79.3, 79.8, 78.4, 79., 78.4, 78.4, 79.4, 79.5, 79.4, 79.3, 79.2,
79.2, 79.3, 79.6, "", 79.2, 79.3, 79., 79.1, 79.2}

Grid[Prepend[Transpose@{data, iF[data, 0][[1]], iF[data][[1]], iF[data, 2][[1]]},
{HoldForm[data], HoldForm[intF[data, 0]], HoldForm[iF[data, 1]], HoldForm[iF[data, 2]]}],
ItemStyle -> {Automatic, Automatic, {{{9, 12}, {1, 4}} -> Red,
{{27, 29}, {1, 4}} -> Orange}}, Dividers -> All]


style = {Joined -> True, Mesh -> Full, LabelStyle -> {"Panel", 14},
ImageSize -> 300, PlotStyle -> Directive[{PointSize[.03], Thick}]};

Row[Table[ListLinePlot[MapAt[Style[#, Red, PointSize[Large]] &, dt[[1]],
Position[data, ""]], style, PlotLabel -> dt[[2]]],
{dt, {{data, "data"}, {iF[data, 0][[1]], "iF[data,0]"},
{iF[data, 1][[1]], "iF[data,1]"}}}], Spacer[5]]