【问题标题】:Changing for loops to apply in r更改 for 循环以在 r 中应用
【发布时间】:2016-04-16 04:54:36
【问题描述】:

我在需要n 节点和优先附件参数beta 的函数中有一个很好的随机图形模拟。我使用 for 循环,但是当您将 n 设为非常大时,代码需要很长时间才能运行。我想知道是否可以使用 apply 系列来提高效率。

binfunction <- function(y) { #Set up bins to create preferential attachment
 L <- length(y)
 x <- c(0, cumsum(y))
 U <- runif(1, min = 0 , max = sum(y))
  for(i in 1:L) {
   if(x[i] <= U && x[i+1] > U){
    return(i)
  }
 } 
}

random_graph <- function(n, beta) { #Random graphing function
 mat <- matrix(0,n,n)
 mat[1,2] <- 1
 mat[2,1] <- 1
  for(i in 3:n) {
   degvect <- colSums(mat[ , (1:(i-1))])
   degvect <- degvect^(beta)
   j <- binfunction(degvect)
   mat[i,j] <- 1
   mat[j,i] <- 1
 }
return(mat)
}

它可以用于:

set.seed(123)
random_graph(10, 0.5)

【问题讨论】:

  • 你能提供一个reproducible example吗?
  • @VincentBonhomme 这是一个随机模拟。只需将nbeta 输入random_graph。 (保持 beta 小,即在 0 和 2 之间)
  • 好吧,我编辑了你的问题。
  • 好东西,谢谢
  • 仅使用j &lt;- binfunction(colSums(mat[ , (1:(i-1))])^beta) 即可获得 5% 的收益,但不足以解决您的问题。

标签: r loops apply


【解决方案1】:

如果您追求效率,矢量化是关键。

主要的节省时间(至少对于 big n)是使用样本。

例如:

n <- 1e7                             
sample(0:1, n, replace=TRUE) 

大约需要 0.2 秒,而

for(i in 1:n) sample(0:1, 1)

大约需要 24 秒。矢量化操作通常可以替代循环,但知道何时何地取决于您是否熟悉满足您需求的可用函数。

【讨论】:

    【解决方案2】:

    在处理大图问题时考虑使用稀疏矩阵。使用法线矩阵的计算成本和内存成本都很高。这是一个简短的测试,用库 Matrix 中的 sparseMatrix 替换您的矩阵:

     library(Matrix)
     psidom_random_graph <- function(n, beta) { #Random graphing function
         mat <- sparseMatrix(dims = c(n, n), i = {}, j = {})
         mat[1,2] <- T
         mat[2,1] <- T
         for(i in 3:n) {
             degvect <- colSums(mat[,1:(i-1)])
             degvect <- degvect^beta
             j <- binfunction(degvect)
             mat[i,j] <- T
             mat[j,i] <- T
        }
      return(mat)
    }
    
    > microbenchmark(psidom_random_graph(1000,1), killian_random_graph(1000,1))
    Unit: seconds
                              expr      min       lq     mean   median       uq
      psidom_random_graph(1000, 1) 1.575727 1.593401 1.637430 1.602013 1.666144
     killian_random_graph(1000, 1) 7.031790 7.092761 7.212975 7.192756 7.308052
          max neval
     1.971281   100
     7.552074   100
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-10
      • 1970-01-01
      • 2021-08-11
      • 1970-01-01
      • 1970-01-01
      • 2022-11-19
      • 2020-01-22
      相关资源
      最近更新 更多