# [R] linear interpolation of multiple random time series

Gabor Grothendieck ggrothendieck at gmail.com
Thu Jul 19 21:01:40 CEST 2007

```Thsi can be done compactly using the zoo package.

The first statement after library converts the rows for each trial into
a separate zoo object and then uses by to merge these into a
single zoo object with one column per trial.

The second statement converts it from zoo to ts which has
the effect of filling in all missing times.  na.approx
does the actual linear interpolation.

The result is an mts object (or you could use as.zoo to
convert that to a zoo object if you prefer).

library(zoo)
z <- do.call("merge", by(a, a\$trial, function(DF) zoo(DF\$x, DF\$time)))
na.approx(as.ts(z), na.rm = FALSE)

On 7/19/07, Mike Lawrence <Mike.Lawrence at dal.ca> wrote:
> Hi all,
>
> Looking for tips on how I might more optimally solve this. I have
> time series data (samples from a force sensor) that are not
> guaranteed to be sampled at the same time values across trials. ex.
>
> trial   time    x
> 1       1       1
> 1       5       4
> 1       7       9
> 1       12      20
> 2       1       0
> 2       3       5
> 2       9       10
> 2       13      14
> 2       19      22
> 2       24      32
>
> Within each trial I'd like to use linear interpolation between each
> successive time sample to fill in intermediary timepoints and x-
> values, ex.
>
> trial   time    x
> 1       1       1
> 1       2       1.75
> 1       3       2.5
> 1       4       3.25
> 1       5       4
> 1       6       6.5
> 1       7       9
> 1       8       11.2
> 1       9       13.4
> 1       10      15.6
> 1       11      17.8
> 1       12      20
> 2       1       0
> 2       2       2.5
> 2       3       5
> 2       4       5.83333333333333
> 2       5       6.66666666666667
> 2       6       7.5
> 2       7       8.33333333333333
> 2       8       9.16666666666667
> 2       9       10
> 2       10      11
> 2       11      12
> 2       12      13
> 2       13      14
> 2       14      15.3333333333333
> 2       15      16.6666666666667
> 2       16      18
> 2       17      19.3333333333333
> 2       18      20.6666666666667
> 2       19      22
> 2       20      24
> 2       21      26
> 2       22      28
> 2       23      30
> 2       24      32
>
>
> The solution I've coded (below) involves going through the original
> data frame line by line and is thus very slow (indeed, I had to
> resort to writing to file as with a large data set I started running
> into memory issues if I tried to create the new data frame in
> memory). Any suggestions on a faster way to achieve what I'm trying
> to do?
>
> #assumes the first data frame above is stored as 'a'
> arows = (length(a\$x)-1)
> write('', 'temp.txt')
> for(i in 1:arows){
>        if(a\$time[i+1] > a\$time[i]){
>                write.table(a[i,], 'temp.txt', row.names = F, col.names = F, append
> = T)
>                x1 = a\$time[i]
>                x2 = a\$time[i+1]
>                dx = x2-x1
>                if(dx != 1){
>                        y1 = a\$x[i]
>                        y2 = a\$x[i+1]
>                        dy = y2-y1
>                        slope = dy/dx
>                        int = -slope*x1+y1
>                        temp=a[i,]
>                        for(j in (x1+1):(x2-1)){
>                                temp\$time = j
>                                temp\$x = slope*j+int
>                                write.table(temp, 'temp.txt', row.names = F, col.names = F,
> append = T)
>                        }
>                }
>        }else{
>                write.table(a[i,], 'temp.txt', row.names = F, col.names = F, append
> = T)
>        }
> }
> i=i+1
> write.table(a[i,], 'temp.txt', row.names = F, col.names = F, append = T)
>