如何将矢量附加到矢量 r - 以矢量化样式
How to append a vector to a vector r - in a vectorized style
我们都知道在 R 中的 for 循环中将向量附加到向量是一件坏事,因为它会花费时间。一种解决方案是以 向量化 样式进行。 Here 是 Joshua Ulrich 的一个很好的例子。重要的是首先创建一个已知长度的向量然后填充它,而不是将每个新片段附加到循环中的现有片段。
不过,在他的示例中,他演示了 'only' 如何一次附加一个数据片段。我现在正在与用向量而不是标量填充向量的想法作斗争。
假设我有一个长度为 100 的向量
vector <- numeric(length=100)
和一个更小的向量,可以容纳第一个向量的 10 倍
vec <- seq(1,10,1)
在不使用 c() 或 append 的情况下,我将如何构建一个将较小向量添加到大向量的循环?
编辑:此示例已简化 - vec 并不总是由相同的序列组成,而是在 for 循环中生成,应添加到向量中。
您可以在循环中使用法线向量索引来完成此操作:
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)
将是首选解决方案。
类似的方法,如果你的新向量是可变长度的,可能会更清楚一点:
# 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)
我们都知道在 R 中的 for 循环中将向量附加到向量是一件坏事,因为它会花费时间。一种解决方案是以 向量化 样式进行。 Here 是 Joshua Ulrich 的一个很好的例子。重要的是首先创建一个已知长度的向量然后填充它,而不是将每个新片段附加到循环中的现有片段。
不过,在他的示例中,他演示了 'only' 如何一次附加一个数据片段。我现在正在与用向量而不是标量填充向量的想法作斗争。
假设我有一个长度为 100 的向量
vector <- numeric(length=100)
和一个更小的向量,可以容纳第一个向量的 10 倍
vec <- seq(1,10,1)
在不使用 c() 或 append 的情况下,我将如何构建一个将较小向量添加到大向量的循环?
编辑:此示例已简化 - vec 并不总是由相同的序列组成,而是在 for 循环中生成,应添加到向量中。
您可以在循环中使用法线向量索引来完成此操作:
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)
将是首选解决方案。
类似的方法,如果你的新向量是可变长度的,可能会更清楚一点:
# 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)