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

时间:2010-05-06 04:43:58

标签: r vector performance

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

编辑:我当前的解决方案是使用一个布尔向量,其长度与可以在集合中的事物列表相同,并将其用作成员资格表。

4 个答案:

答案 0 :(得分:14)

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

如果您知道该集合的最终大小是什么,那么您建议的方法可能是最好的 - 即使用适当的成员资格向量来自整个宇宙的subset。很难知道什么是最好的,但没有看到你想要做的事情。

答案 1 :(得分:13)

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

e.g。

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

答案 2 :(得分:4)

很难说你想要什么。也许你真的想要像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. 

答案 3 :(得分:1)

是的,还有更有效的方法。

这取决于您如何使用数据;您的用例。您是按照数据放置的顺序,反转的顺序,随机的顺序还是排序的顺序取出数据?

对于FIFO,对于固定大小的数组,请使用circular buffer;对于完全动态大小,请使用deque(读音卡组)。 (这可能就是您想要的。)

对于FILO,请使用stack

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

如果需要有序集合(例如c(3,2,5) -> c(2,3,5)),请查看tree or a heap

  • 一棵树很适合进行比较,例如,获取<5.5中的所有元素。
  • 堆非常适合仅捕获最大或最小的元素。