【问题标题】:alternative of for loop in RR中for循环的替代方案
【发布时间】:2020-09-13 06:41:16
【问题描述】:

cell_support_xyz <- function(level, zero)
{
  for(i in 1:level[1]){
    for(j in 1:level[2]){
      for(k in 1:level[3]){
        cat("cell (", i, ", ", j, ", ", k,") --> support set = (", 
            +!(i == zero[1]), ", ", +!(j == zero[2]), ", ", +!(k == zero[3]), ")\n", sep = "")
        
      }      
    }
  }
}


#Example 1
l<-c(2,3,2)
z<-c(1,1,1)
> cell_support_xyz(l,z)

cell (1, 1, 1) --> support set = (0, 0, 0)
cell (1, 1, 2) --> support set = (0, 0, 1)
cell (1, 2, 1) --> support set = (0, 1, 0)
cell (1, 2, 2) --> support set = (0, 1, 1)
cell (1, 3, 1) --> support set = (0, 1, 0)
cell (1, 3, 2) --> support set = (0, 1, 1)
cell (2, 1, 1) --> support set = (1, 0, 0)
cell (2, 1, 2) --> support set = (1, 0, 1)
cell (2, 2, 1) --> support set = (1, 1, 0)
cell (2, 2, 2) --> support set = (1, 1, 1)
cell (2, 3, 1) --> support set = (1, 1, 0)
cell (2, 3, 2) --> support set = (1, 1, 1)

上面的代码工作得很好。但我想避免 for 循环。这里我使用了 3 个 for 循环(因为两个参数向量的长度都是 3)。如果向量的长度增加或减少,该功能将不起作用(我需要相应地调整 for 循环);这就是为什么我想用一些适用于任何长度的有效替代方法来替换 for-loop。有什么建议吗?

【问题讨论】:

    标签: r for-loop


    【解决方案1】:

    一种删除for 循环并使解决方案足够灵活以适应任何长度输入的方法。

    我们使用expand.grid 创建level 的所有可能组合,并使用apply 按行创建要打印的字符串。

    cell_support_xyz <- function(level, zero) {
      tmp <- do.call(expand.grid, lapply(level, seq))
      abc <- apply(tmp, 1, function(x) 
                   cat(sprintf('cell (%s) --> support set = (%s)\n', 
                       toString(x), toString(+(x != zero)))))
    }
    
    l<-c(2,3,2)
    z<-c(1,1,1)
    
    cell_support_xyz(l, z)
    #cell (1, 1, 1) --> support set = (0, 0, 0)
    #cell (2, 1, 1) --> support set = (1, 0, 0)
    #cell (1, 2, 1) --> support set = (0, 1, 0)
    #cell (2, 2, 1) --> support set = (1, 1, 0)
    #cell (1, 3, 1) --> support set = (0, 1, 0)
    #cell (2, 3, 1) --> support set = (1, 1, 0)
    #cell (1, 1, 2) --> support set = (0, 0, 1)
    #cell (2, 1, 2) --> support set = (1, 0, 1)
    #cell (1, 2, 2) --> support set = (0, 1, 1)
    #cell (2, 2, 2) --> support set = (1, 1, 1)
    #cell (1, 3, 2) --> support set = (0, 1, 1)
    #cell (2, 3, 2) --> support set = (1, 1, 1)
    

    【讨论】:

    • 你能解释一下吗,因为这对我来说是新的。特别是 sprintf function(x) cat(sprintf('cell (%s) --&gt; support set = (%s)\n', toString(x), toString(+(x != zero))))
    • toString 结合x 的值并给出一个逗号分隔的字符串。请参阅 x &lt;- c(1, 0, 1)toString(x)%s 是占位符,我们将每一行的 toString(x) 的值放在 tmp 中,对于 toString(+(x != zero)) 也是如此。以sprintf('cell (%s) --&gt; support set = (%s)\n', toString(x), toString(+(x != z))) 为例,这可能有助于从您的帖子中了解xx &lt;- c(1, 0, 1)z 的位置。
    【解决方案2】:

    您可以分两步完成:

    l<-c(2,3,2)
    z<-c(1,1,1)
    
    cells <- expand.grid(lapply(l, seq))
    
    t(apply(cells, 1, function(x) 1L*!(x == z)))
    

    cells 包含所有组合。如果订单很重要,您可以简单地重新排序:

    cells <- dplyr::arrange(cells, Var1, Var2, Var3)
    

    然后,对于每一行 (apply(,1,)),您可以使用已矢量化的 == 将整行与整个 z 向量进行比较。

    乘以1L 使其成为整数,与+ 相同。

    【讨论】:

      猜你喜欢
      • 2015-07-30
      • 1970-01-01
      • 2020-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      相关资源
      最近更新 更多