insert elements in a vector in R

后端 未结 6 1541
悲哀的现实
悲哀的现实 2020-12-01 16:11

I have a vector in R,

a = c(2,3,4,9,10,2,4,19)

let us say I want to efficiently insert the following vectors, b, and c,

b =         


        
6条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-01 16:38

    After using Ferdinand's function, I tried to write my own and surprisingly it is far more efficient.
    Here's mine :

    insertElems = function(vect, pos, elems) {
    
    l = length(vect)
      j = 0
      for (i in 1:length(pos)){
        if (pos[i]==1)
          vect = c(elems[j+1], vect)
        else if (pos[i] == length(vect)+1)
          vect = c(vect, elems[j+1])
        else
          vect = c(vect[1:(pos[i]-1+j)], elems[j+1], vect[(pos[i]+j):(l+j)])
        j = j+1
      }
      return(vect)
    }
    
    tmp = c(seq(1:5))
    insertElems(tmp, c(2,4,5), c(NA,NA,NA))
    # [1]  1 NA  2  3 NA  4 NA  5
    
    insert.at(tmp, c(2,4,5), c(NA,NA,NA))
    # [1]  1 NA  2  3 NA  4 NA  5
    

    And there's the benchmark result :

    > microbenchmark(insertElems(tmp, c(2,4,5), c(NA,NA,NA)), insert.at(tmp, c(2,4,5), c(NA,NA,NA)), times = 10000)
    Unit: microseconds
                                            expr    min     lq     mean median     uq      max neval
     insertElems(tmp, c(2, 4, 5), c(NA, NA, NA))  9.660 11.472 13.44247  12.68 13.585 1630.421 10000
       insert.at(tmp, c(2, 4, 5), c(NA, NA, NA)) 58.866 62.791 70.36281  64.30 67.923 2475.366 10000
    

    my code works even better for some cases :

    > insert.at(tmp, c(1,4,5), c(NA,NA,NA))
    # [1]  1  2  3 NA  4 NA  5 NA  1  2  3
    # Warning message:
    # In result[c(TRUE, FALSE)] <- split(a, cumsum(seq_along(a) %in% (pos))) :
    #   number of items to replace is not a multiple of replacement length
    
    > insertElems(tmp, c(1,4,5), c(NA,NA,NA))
    # [1] NA  1  2  3 NA  4 NA  5
    

提交回复
热议问题