如何在R中写入for循环次数的循环?

时间:2015-06-13 17:41:26

标签: r loops

这可能是一个简单的问题,但我不知所措......

我需要很多循环才能获得支持中每个样本的结果,就像通常的堆叠循环一样:

for (a in 1:N1){
 for (b in 1:N2){
  for (c in 1:N3){
   ...
   }
  }
}

但是这个凌乱系统所需的for循环次数取决于另一个随机变量,比方说,     for(f in 1:N.for)

那么如何编写for循环来处理这个问题呢?或者有更优雅的方法来做到这一点?

请注意,不同之处在于上面的嵌套for循环(变量a,b,c,...)在我的计算中很重要,但是for循环的变量f控制了for循环的数量为了我的真实目的,我不会进行任何计算 - 所有这一切都是计算/确保所需的for循环次数是正确的。

我说清楚了吗?

所以我实际上要做的就是产生许多人对他人偏好的所有可能组合。

假设我有6个人(对我来说最简单的情况):Abi,Bob,Cath,Dan,Eva,Fay。

Abi和Bob有C D E F的偏好列表(4!=每种可能的24种排列);

Cath和Dan分别有A B和E F的偏好列表(2!* 2!= 4个可能的排列);

Eva和Fay有A B C D的偏好列表(4!=每个可能的排列24个);

因此,当将所有六个一起放在一起时,应该有24 * 24 * 4 * 4 * 24 * 24个可能的偏好排列。

我只是想知道什么是一个清晰,简单和系统的方法来同时生成它们?

我希望它们的格式如

c.prefs <- as.matrix(data.frame(Abi = c("Eva", "Fay", "Dan", "Cath"),Bob = c("Dan", "Eva", "Fay", "Cath"))

但任何明确的格式都可以......

非常感谢!!

2 个答案:

答案 0 :(得分:2)

我假设你有一个每个循环变量及其最大值的列表,从最外层到最里面的变量排序。

loops <- list(a=2, b=3, c=2)

您可以使用以下正确顺序创建一个包含所有循环变量值的数据框:

(indices <- rev(do.call(expand.grid, lapply(rev(loops), seq_len))))
#    a b c
# 1  1 1 1
# 2  1 1 2
# 3  1 2 1
# 4  1 2 2
# 5  1 3 1
# 6  1 3 2
# 7  2 1 1
# 8  2 1 2
# 9  2 2 1
# 10 2 2 2
# 11 2 3 1
# 12 2 3 2

如果在嵌套循环的最内部运行的代码不依赖于先前的迭代,则可以使用apply之类的东西来独立处理每个迭代。否则,您可以使用单个循环遍历数据框的行:

for (i in seq_len(nrow(indices))) {
  # You can get "a" with indices$a[i], "b" with indices$b[i], etc.
}

答案 1 :(得分:0)

对于计算的方式,一个选项是使用Reduce函数或其他一些高阶函数。

由于您的数据不是固有的排序(个人是集合的一部分,其偏好是集合的一部分),我会将个体保持在一个因素中,并且例如在个人命名的列表中具有偏好。如果您有大量数据,则可以将其存储在环境中。

第一个代码就是如何使其可重现。问题域类似于面向图形的命名。您只需要在第一行和runif中进行更改以更改行为。

    #people
    verts <- factor(c(LETTERS[1:10]))

    #relations, disallow preferring yourself
    edges<-lapply(seq_along(verts), function(ind) {
      levels(verts)[-ind]
    })
    names(edges) <- levels(verts)

    #directions
    #say you have these stored in a list or something
    pool <- levels(verts)
    directions<-lapply(pool, function(vert) {
      relations <- pool[unique(round(runif(5, 1, 10)))]
      relations[!(vert %in%  relations)]
    })
    names(directions) = pool

    num_prefs <- (lapply(directions, length))
    names(num_prefs) <- names(directions)

    #First take factorial of each persons preferences, 
    #then reduce that with multiplication
    combinations <-
    Reduce(`*`, 
           sapply(num_prefs, factorial)
    )

我希望这能回答你的问题!