Search code examples
rtime-series

Data frame "expand" procedure in R?


This is not a real statistical question, but rather a data preparation question before performing the actual statistical analysis. I have a data frame which consists of sparse data. I would like to "expand" this data to include zeroes for missing values, group by group.

Here is an example of the data (a and b are two factors defining the group, t is the sparse timestamp and xis the value):

test <- data.frame(
    a=c(1,1,1,1,1,1,1,1,1,1,1),
    b=c(1,1,1,1,1,2,2,2,2,2,2),
    t=c(0,2,3,4,7,3,4,6,7,8,9),
    x=c(1,2,1,2,2,1,1,2,1,1,3))

Assuming I would like to expand the values between t=0 and t=9, this is the result I'm hoping for:

test.expanded <- data.frame(
    a=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
    b=c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2),
    t=c(0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9),
    x=c(1,0,2,1,2,0,0,2,0,0,0,0,0,1,1,0,2,1,1,3))

Zeroes have been inserted for all missing values of t. This makes it easier to use.

I have a quick and dirty implementation which sorts the dataframe and loops through each of its lines, adding missing lines one at a time. But I'm not entirely satisfied by the solution. Is there a better way to do it?

For those who are familiar with SAS, it is similar to the proc expand.

Thanks!


Solution

  • As you noted in a comment to the other answer, doing it by group is easy with plyr which just leaves how to "fill in" the data sets. My approach is to use merge.

    library("plyr")
    
    test.expanded <- ddply(test, c("a","b"), function(DF) {
      DF <- merge(data.frame(t=0:9), DF[,c("t","x")], all.x=TRUE)
      DF[is.na(DF$x),"x"] <- 0
      DF
    })
    

    merge with all.x=TRUE will make the missing values NA, so the second line of the function is needed to replace those NAs with 0's.