R - 多个循环计数器变量

时间:2018-02-14 13:58:22

标签: r for-loop

我需要编写循环,其中每个迭代都有一组唯一的变量值。它不是一个嵌套循环"对于每个我做(对于每个j do)"类型问题。下面只是一个示例问题,循环正在做的事情并不重要,它可以为循环的每次迭代使用多个变量。

简单循环:

df <- data.frame(num = 1:5)
lookup <- data.frame(colors = c("red", "green", "blue"), 
                     pets = c("cat", "dog", "rabbit"),
                     stringsAsFactors = FALSE)
for (color in lookup$colors) {
  df[, color] <- 1
}

我想做什么(伪代码):

for (color, pet in lookup$colors, lookup$pets) {
  df[, color] <- pet
}

我提出的最佳方法如下,但附加的r [&#34; &#34;]使代码更难阅读:

for (i in 1:nrow(lookup)) {
  r <- unlist(lookup[i, ])
  df[, r["colors"]] <- r["pets"]
}

df
  num red green   blue
1   1 cat   dog rabbit
2   2 cat   dog rabbit
3   3 cat   dog rabbit
4   4 cat   dog rabbit
5   5 cat   dog rabbit

我想知道对这类问题最好的一般方法是什么。在许多情况下,您可以使用要为每组变量调用的函数替换循环,但在某些情况下函数不适合。

1 个答案:

答案 0 :(得分:1)

对于您的具体示例,您将以正确的心态去实现它。要稍微清理它并减少错误的机会,你可以将循环重写为:

for (i in seq_len(nrow(lookup))) {
  color_i <- lookup[i, "colors"]
  pet_i <- lookup[i, "pets"]
  df[[color_i]] <- pet_i
}

没有那么不同,但seq_len避免了lookup零行的问题。在这种情况下,1:nrow(lookup)会返回c(1, 0)。而且我的循环内容是否易于阅读可能是主观的。

如果有帮助,针对您的具体问题的单行解决方案是:

df[, lookup[["colors"]]] <- lapply(lookup[["pets"]], rep, nrow(df))

切线相关

我会说你的例子是R中的一个特例,你在迭代地修改现有的对象。大多数时候,人们只想迭代多个向量并将结果存储在新的向量中。例如:

results <- list()

for (i in seq_len(nrow(lookup))) {
  color_i <- lookup[i, "colors"]
  pet_i <- lookup[i, "pets"]
  results[[i]] <- do_something(color_i, pet_i)
}

更好的方法是使用mapply

results <- mapply(FUN = do_something, lookup[["colors"]], lookup[["pets"]])