Search code examples
rfunctionsampling

Adding zeros in middle of sequence in R (Like upsampling)


I am wondering if there is any function in R for upsampling since I could not find anything even close to Matlab upsample(x, upsampling_factor). There are functions with the name upsample but they are very confusing to use, I need pretty much something that adds predefined zeros between two numbers. Any other functions that take the input signal X like [1,2,3,4] and turn it to something like [1 0 0 2 0 0 3 0 0 4 0 0] is fine. This is like upsampling factor 3.


Solution

  • Taking a lead from here a few options:

    upsample1 = function(x, upsampling_factor)
      c(rbind(x, matrix(0, nc=length(x), nr=upsampling_factor-1)))    
    
    upsample2 = function(x, upsampling_factor){
      v = numeric(length(x)*upsampling_factor)
      v[seq(1, length(x)*upsampling_factor, by=upsampling_factor)]=x
      v
    }      
    
    upsample3 = function(x, upsampling_factor) 
      c(kronecker(x, c(1, rep(0, upsampling_factor-1))))
    
    # d.b -- this looks a wee bit faster
    upsample4 = function(x, upsampling_factor) 
       replace(rep(0, upsampling_factor * length(x)), 
          1:(upsampling_factor*length(x)) %% upsampling_factor == 1, x)
    

    For interest

    all.equal(upsample1(x=1e5, 4), upsample2(x=1e5, 4))
    all.equal(upsample3(x=1e5, 4), upsample2(x=1e5, 4))
    
    microbenchmark::microbenchmark(upsample1(x=1e5, 4),
                                   upsample2(x=1e5, 4),
                                   upsample3(x=1e5, 4),
                                   upsample4(x=1e5, 4))
    
    # Unit: microseconds
    #                     expr    min      lq     mean  median      uq     max neval cld
    #  upsample1(x = 1e+05, 4)  9.080 10.6515 11.72813 11.8735 12.4325  24.025   100  a  
    #  upsample2(x = 1e+05, 4) 38.902 42.6740 45.14167 44.1400 46.4450  90.864   100  b 
    #  upsample3(x = 1e+05, 4) 62.368 65.8610 69.69082 67.4325 70.6795 187.455   100  c
    #  upsample4(x = 1e+05, 4)  7.613  8.8705  9.57149  9.5690 10.0570  19.137   100  a