【问题标题】:How to append a vector to a vector r - in a vectorized style如何将向量附加到向量 r - 以向量化样式
【发布时间】:2015-05-13 21:20:10
【问题描述】:

我们都知道,在 R 的 for 循环中将向量附加到向量是一件坏事,因为它会耗费时间。一种解决方案是以 vectorized 样式进行。 Here 是 Joshua Ulrich 的一个很好的例子。重要的是首先创建一个已知长度的向量,然后将其填充,而不是将每个新片段附加到循环中的现有片段。

不过,在他的示例中,他“仅”演示了如何一次附加一个数据。我现在正在与用向量填充向量而不是标量的想法作斗争。

假设我有一个长度为 100 的向量

vector <- numeric(length=100)

和一个较小的向量,可以将 10 次放入第一个向量中

vec <- seq(1,10,1)

在不使用 c() 或 append 的情况下,我将如何构建一个将较小向量添加到大向量的循环?

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

【问题讨论】:

  • 将较小的向量添加到较大的向量中是什么意思?你想要的输出会是什么样子?换句话说,您是在寻找vector + vec 还是paste0(vector, vec)?目前还不是很清楚。
  • 抱歉问题不清楚。原则上我会寻找一个重复的 c (vector, vec)。

标签: r vector vectorization


【解决方案1】:

您可以在循环中使用法线向量索引来完成此操作:

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) 将是首选解决方案。

【讨论】:

  • vector + vec有什么区别?
  • @DavidArenburg 在这个解决方案中所有空间都是预先分配的。如果你做了 10 次 vector+vec,那么你需要 10 次重新分配。
  • 但为什么是 10 次?您只能执行一次。
  • 你建议什么代码? OP 正在寻找一个 for 循环来获得 rep(1:10, 10) 的结果。
  • 我建议对其进行矢量化处理,然后在循环之外执行vector + vec
【解决方案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 在 cmets 中所建议的那样,列表会更加 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)

【讨论】:

  • 嗯,您的第一个代码 sn-p 在循环中不包含任何“i”。不同的 1:10 去哪儿了? “大小”应该是 = i 吗?
  • @Jens for 循环是一个计数器,表示“执行这些命令 10 次”。由于我每次都在做同样的事情,并分别跟踪矢量索引,i 不需要在循环内。您的示例有一个向量 vec 总是长度为 10,但向量正在改变。我的 for 循环展示了一种处理向量的方法,即使长度也会发生变化。 sample 只是每次为示例绘制随机长度的一种方式。 size 绝对应该是 1,因为向量只有一个长度。 (这是一种比假设长度始终相同的更通用的方法。)
  • 作为不使用i 的for 循环的一个非常简单的示例,for(i in 1:5) print("Hello") 将打印“Hello”5 次。每次都做同样的事情,所以我们不需要 i 在循环内。
  • 哇,谢谢,我不知道。学到了新东西,很棒。
猜你喜欢
  • 2015-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
相关资源
最近更新 更多