代码之家  ›  专栏  ›  技术社区  ›  Ryan C. Thompson

有效地向r中的向量或列表添加或删除元素?

  •  13
  • Ryan C. Thompson  · 技术社区  · 16 年前

    我正在实现一种算法,它涉及到从集合中添加和删除很多东西。在R中,这是缓慢的,因为据我所知,从一个向量中添加或删除东西是缓慢的,因为必须重新分配整个向量。有没有办法更有效地做到这一点?

    编辑:我目前的解决方案是使用一个与集合中的内容列表长度相同的布尔向量,并将其用作成员表。

    4 回复  |  直到 8 年前
        1
  •  14
  •   James    9 年前

    第2章 The R Inferno 对此有一些有趣的评论,包括Perdiodic增长对象以减少内存碎片和分配开销。

    如果你知道集合的最终大小,那么你建议的方法可能是最好的-ie subset 从整个宇宙使用一个适当的成员向量。很难知道什么是最好的,却看不到你到底想做什么。

        2
  •  13
  •   wkmor1    16 年前

    如果可以,初始化一个向量使其长度等于算法期间的最大长度可能会有所帮助。

    例如

    vec <- rep(NA,10)
    vec[1:3] <- 1:3
    vec[4:5] <- 4:5
    vec[6:10] <- 6:10
    

    而不是

    vec <- 1:3
    vec <- c(vec,4:5)
    vec <- c(vec,6:10)
    

    比较

    > system.time({vec <- rep(NA,10^4); for (i in 1:(10^4)) vec[i] <- i })
       user  system elapsed 
      0.043   0.001   0.044 
    

    > system.time({vec <- NULL; for (i in 1:(10^4)) vec <- c(vec,i) })
       user  system elapsed 
      0.249   0.089   0.335
    
        3
  •  4
  •   John    12 年前

    很难说你想要什么。也许你真的想要像push和pop这样的堆栈命令。以下不是。但这是一个快速的解决方案。

    分配一个足够大的向量来容纳所需类型的所有项。将每个值设置为na。添加项很简单。删除项目将再次设置为NA。使用矢量只是 na.omit(myVec)

    myVec <- numeric (maxLength)  # a vector of maximum length
    
    is.na(myVec) <- 1:maxLength   # set every item in myVec to NA
    
    myVec[c(2,6,20)] <- 5         # add some values
    
    na.omit(myVec)
    
    #This will also work if you can initialize all of your values to something that you know you won't need. 
    
        4
  •  1
  •   Danielle    8 年前

    是的,有更有效的方法。

    归根结底,这取决于您如何使用数据;您的用例。您是按放入的顺序取出数据,还是按相反顺序取出数据,还是按随机顺序取出数据,还是按排序顺序取出数据?

    为了 FIFO ,对于固定大小的数组,请使用 circular buffer 或者对于完全动态的大小,请使用 deque (明显的甲板)。(这可能是你想要的。)

    为了 FILO 使用A stack .

    对于随机获取数据,请考虑使用从不调整大小的1列矩阵。调整大小很慢。

    如果你需要一套有序的(如 c(3,2,5) -> c(2,3,5) 看一看 tree or a heap .

    • 树有利于比较,例如在一个集合(即<5.5)中获取所有元素。
    • 堆很适合只捕获最大或最小的元素。
    推荐文章