如何将矢量附加到矢量r - 以矢量化的样式

时间:2015-03-11 21:19:33

标签: r vector vectorization

我们都知道,向 R 中的for循环中的向量追加向量是一件坏事,因为它需要花费时间。解决方案是以矢量化样式执行此操作。 Here是约书亚乌尔里希的一个很好的例子。重要的是首先创建一个已知长度的矢量,然后将其填满,而不是将每个新片段附加到循环中的现有片段。

尽管如此,在他的例子中,他还展示了“仅”如何一次附加一个数据片段。我现在正在努力用矢量填充矢量 - 而不是标量。

想象一下,我有一个长度为100的矢量

vector <- numeric(length=100)

和一个较小的矢量,可以在第一个矢量中适合10次

vec <- seq(1,10,1)

我如何构建一个循环,将较小的向量添加到大型向量而不使用c()或追加?

编辑:这个例子是简化的 - vec并不总是由相同的序列组成,而是在for循环中生成,应该添加到vector中。

2 个答案:

答案 0 :(得分:3)

您可以在循环中使用法向量索引来完成此任务:

vector <- numeric(length=100)
for (i in 1:10) {
  vector[(10*i-9):(10*i)] <- 1:10
}
all.equal(vector, rep(1:10, 10))
# [1] TRUE

当然,如果您只是尝试重复一次向量,则rep(vec, 10)将成为首选解决方案。

答案 1 :(得分:2)

类似的方法,如果您的新向量具有可变长度,可能会更清楚一点:

# Let's over-allocate so that we now the big vector is big enough
big_vec = numeric(1e4)

this.index = 1

for (i in 1:10) {
    # Generate a new vector of random length
    new_vec = runif(sample(1:20, size = 1))
    # Stick in in big_vec by index
    big_vec[this.index:(this.index + length(new_vec) - 1)] = new_vec
    # update the starting index
    this.index = this.index + length(new_vec)
}

# truncate to only include the added values   
big_vec = big_vec[1:(this.index - 1)]

正如@josilber在评论中所建议的,列表会更多R-ish。这是一种更清晰的方法,除非新的向量生成依赖于先前的向量,在这种情况下,for循环可能是必要的。

vec_list = list()
for (i in 1:10) {
    # Generate a new vector of random length
    vec_list[[i]] = runif(sample(1:20, size = 1))
}

# Or, use lapply
vec_list = lapply(1:10, FUN = function(x) {runif(sample(1:20, size = 1))})

# Then combine with do.call
do.call(c, vec_list)

# or more simply, just unlist
unlist(vec_list)