【问题标题】:R:for loop execution time?R:for循环执行时间?
【发布时间】:2016-03-14 06:30:06
【问题描述】:

有没有办法估计一个 for 循环需要多长时间运行?我有一个包含大约 500,000 次迭代的循环,它执行一些基本计算,并且已经运行了一段时间。我怀疑这可能是一个永无止境的循环。

代码如下:

mod<- function(file, level = 5){
  df<- read.csv(file = file,header = FALSE,sep = "", col.names = c("DateTime","Seq","BP1","BQ1","BO1","AP1","AQ1","AO1","BP2","BQ2","BO2","AP2","AQ2","AO2","BP3","BQ3","BO3","AP3","AQ3","AO3","BP4","BQ4","BO4","AP4","AQ4","AO4","BP5","BQ5","BO5","AP5","AQ5","AO5","BP6","BQ6","BO6","AP6","AQ6","AO6","BP7","BQ7","BO7","AP7","AQ7","AO7","BP8","BQ8","BO8","AP8","AQ8","AO8","BP9","BQ9","BO9","AP9","AQ9","AO9","BP10","BQ10","BO10","AP10","AQ10","AO10","C","Price","Qty","OldPrice","OldQty"))
  df<- df[which(df$DateTime != 0),]
  df$DateTime= as.POSIXct(df$DateTime/(10^9), origin="1970-01-01")    #timestamp conversion
  change = c()
  for(i in 2:nrow(df)){
    if(is.na(df[i,6]) == TRUE){
      change[i] = 0
      next
    } else if(is.na(df[i,63]) == TRUE){
      change[i] = 0
      next
    }
    #browser()
    if(df[i,63] == "N"){
      a = which(df[i,] == df[i,64])
      if(a[1] > 32){
        change[i] = 0
      } else if(a[1] < 32){
        change[i] = a[1]
      }
      change
    }
    #browser()
    if(df[i,63] == "C"){
      a = which(df[i,] == df[i,64])
      if(a[1] > 32){
        change[i] = 0
      }else if(a[1] < 32){
        change[i] = a[1]*-1
      }
      change
    }
    #browser()
    if(df[i,63] == "M"){
      a = which(df[i,] == df[i,64])
      b = which(df[i-1,] == df[i,66])
      if(a[1] > 32 & b[1] > 32){
        change[i] = 0
      } else if(a[1] < 32 & b[1] > 32){
        change[i] = a[1]
      } else if(a[1] < 32 & b[1] < 32){
        change[i] = b[1] - a[1]
      }
      #browser()
      change
    }
    change
  }
  change
}

我要做的是首先查看第 63 列(“C”)的内容,如果它是“N”或“C”,然后查看第 64 列(“价格”)并找到它在该行中的位置,除了第 64 列本身,然后将列号分配给 改变[i]。如果 col63 为“C”则为负数,如果 col63 为“N”则为正数

如果第 63 列(“C”)显示“M”,则首先查看第 66 列(“OldPrice”)并将其定位到上一行 i-1。然后在同一行的第 64 列(“价格”)中找到价格,并取它们之间的差异(列号)并将其分配给 change[i]

所以输出应该是一个负整数或正整数的向量。

> dput(df[1:20,])
structure(list(DateTime = c(1.448855100369e+18, 1.448855100369e+18, 
1.448855100375e+18, 1.448855100376e+18, 1.448855100378e+18, 1.448855100379e+18, 
1.44885510038e+18, 1.44885510038e+18, 1.44885510038e+18, 1.448855100383e+18, 
1.448855100384e+18, 1.448855100385e+18, 1.448855100385e+18, 1.448855100385e+18, 
1.448855100386e+18, 1.448855100386e+18, 1.448855100386e+18, 1.448855100387e+18, 
1.448855100389e+18, 1.448855100389e+18), Seq = c(92L, 108L, 406L, 
479L, 643L, 722L, 811L, 822L, 828L, 1046L, 1103L, 1171L, 1186L, 
1196L, 1238L, 1249L, 1254L, 1273L, 1333L, 1343L), BP1 = c(80830L, 
80830L, 81100L, 81100L, 81100L, 81100L, 81100L, 81100L, 81100L, 
81100L, 81100L, 81100L, 81100L, 81100L, 81100L, 81100L, 81200L, 
81200L, 81200L, 81200L), BQ1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), BO1 = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L), AP1 = c(0L, 83435L, 83435L, 82165L, 82165L, 82165L, 
82165L, 82165L, 82345L, 82345L, 82165L, 82345L, 82345L, 82165L, 
82340L, 82340L, 82340L, 82340L, 82165L, 82340L), AQ1 = c(0L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L), AO1 = c(0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), BP2 = c(0L, 0L, 80830L, 
80830L, 80830L, 80830L, 80830L, 80835L, 80835L, 80835L, 80835L, 
80835L, 80835L, 80835L, 80835L, 80835L, 81100L, 81100L, 81100L, 
81100L), BQ2 = c(0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), BO2 = c(0L, 0L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
), AP2 = c(0L, 0L, 0L, 83435L, 83200L, 82650L, 82650L, 82650L, 
82650L, 82650L, 82650L, 82650L, 82650L, 82650L, 82650L, 82650L, 
82650L, 82650L, 82650L, 82650L), AQ2 = c(0L, 0L, 0L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), 
    AO2 = c(0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L), BP3 = c(0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 80830L, 80830L, 80830L, 80830L, 80830L, 80830L, 80830L, 
    80830L, 80830L, 80835L, 80835L, 80835L, 80835L), BQ3 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L), BO3 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), AP3 = c(0L, 
    0L, 0L, 0L, 83435L, 83200L, 83200L, 83200L, 83200L, 83200L, 
    83200L, 83200L, 82900L, 82900L, 82900L, 82900L, 82900L, 82900L, 
    82900L, 82900L), AQ3 = c(0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), AO3 = c(0L, 
    0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L), BP4 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 80830L, 80830L, 80830L, 80830L
    ), BQ4 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L), BO4 = c(0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 
    1L), AP4 = c(0L, 0L, 0L, 0L, 0L, 83435L, 83430L, 83430L, 
    83430L, 83430L, 83430L, 83430L, 83200L, 83200L, 83200L, 83200L, 
    83200L, 83200L, 83200L, 83200L), AQ4 = c(0L, 0L, 0L, 0L, 
    0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
    2L), AO4 = c(0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), BP5 = c(0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 80035L, 
    80035L, 80035L), BQ5 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L), BO5 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 1L, 1L, 1L), AP5 = c(0L, 0L, 0L, 0L, 0L, 0L, 83435L, 
    83435L, 83435L, 83435L, 83435L, 83435L, 83430L, 83430L, 83430L, 
    83430L, 83430L, 83430L, 83430L, 83430L), AQ5 = c(0L, 0L, 
    0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L), AO5 = c(0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), BP6 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), BQ6 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), BO6 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), AP6 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 83500L, 83500L, 83500L, 83435L, 83435L, 83435L, 83435L, 
    83435L, 83435L, 83435L, 83435L), AQ6 = c(0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L), AO6 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), BP7 = c(0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L), BQ7 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), BO7 = c(0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L), AP7 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 83500L, 83500L, 83500L, 83500L, 83500L, 83500L, 
    83500L, 83500L), AQ7 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), AO7 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L), BP8 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), BQ8 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), BO8 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), AP8 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), AQ8 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), AO8 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), BP9 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), BQ9 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), BO9 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), AP9 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), AQ9 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), AO9 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), BP10 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), BQ10 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), BO10 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), AP10 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), AQ10 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), AO10 = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), C = structure(c(4L, 4L, 4L, 4L, 4L, 4L, 
    4L, 4L, 3L, 4L, 3L, 3L, 4L, 3L, 3L, 4L, 4L, 4L, 3L, 3L), .Label = c("", 
    "C", "M", "N"), class = "factor"), Price = c(80830L, 83435L, 
    81100L, 82165L, 83200L, 82650L, 83430L, 80835L, 82345L, 83500L, 
    82165L, 82345L, 82900L, 82165L, 82340L, 83200L, 81200L, 80035L, 
    82165L, 82340L), Qty = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), OldPrice = c(NA, 
    NA, NA, NA, NA, NA, NA, NA, 82165L, NA, 82345L, 82165L, NA, 
    82345L, 82165L, NA, NA, NA, 82340L, 82165L), OldQty = c(NA, 
    NA, NA, NA, NA, NA, NA, NA, 1L, NA, 1L, 1L, NA, 1L, 1L, NA, 
    NA, NA, 1L, 1L)), .Names = c("DateTime", "Seq", "BP1", "BQ1", 
"BO1", "AP1", "AQ1", "AO1", "BP2", "BQ2", "BO2", "AP2", "AQ2", 
"AO2", "BP3", "BQ3", "BO3", "AP3", "AQ3", "AO3", "BP4", "BQ4", 
"BO4", "AP4", "AQ4", "AO4", "BP5", "BQ5", "BO5", "AP5", "AQ5", 
"AO5", "BP6", "BQ6", "BO6", "AP6", "AQ6", "AO6", "BP7", "BQ7", 
"BO7", "AP7", "AQ7", "AO7", "BP8", "BQ8", "BO8", "AP8", "AQ8", 
"AO8", "BP9", "BQ9", "BO9", "AP9", "AQ9", "AO9", "BP10", "BQ10", 
"BO10", "AP10", "AQ10", "AO10", "C", "Price", "Qty", "OldPrice", 
"OldQty"), row.names = c(NA, 20L), class = "data.frame")

【问题讨论】:

  • 我所见过的任何估计和添加时间条的东西也会增加相当大的计算成本,从而使整个事情花费更长的时间。您可以通过矢量化来严重加速该代码,但效率非常低。
  • 有什么建议吗?
  • 您目前的问题似乎更多是关于估计时间,在这种情况下,我建议您查看microbenchmark()。矢量化确实可以加快速度,但可能是另一个问题的答案。
  • 您应该说明如何构建所需输出的逻辑以及典型输入的示例。另请注意,某些仅包含change 的行不会导致函数退出并返回change(如果这是您的意图)。你应该声明return(change)。请记住,只有当它是 last 评估的表达式时,才会返回表达式的结果。在某些情况下似乎并非如此。
  • 举例说明输入数据和预期输出。

标签: r for-loop


【解决方案1】:

我会这样做。唯一需要的循环是应用which,这应该很快:

#find column matches for price
DF$change <- apply(DF[, 3:62] == DF[,64], 1, which) + 2L
#negative for C
DF$change[DF[,63] == "C"] <- DF$change[DF[,63] == "C"] * (-1)
#column matches for old price in preceding row if M
pos2 <- apply(DF[which(DF[,63] == "M") - 1, 3:62] == DF[DF[,63] == "M",66], 1, which) + 2L
#assign the difference
DF$change[DF[,63] == "M"] <- pos2 - DF$change[DF[,63] == "M"]
DF$change
#[1]  3  6  3  6 12 12 24  9  0 36  0  0 18  0  0 24  3 27  0  0

这假设总是有一个匹配的列。如果不是这种情况,则将which 包装在一个返回NA 的函数中,如果which 返回integer(0)

【讨论】:

  • DF$change[DF[,63] == "C"] Error in df$change[df[, 63] == "C"] * (-1) : non-numeric argument to binary operator 我尝试先生成具有“C”的行,然后乘以 -1,但这也没有用
  • 注意DF 的不同大小写。 (我不喜欢调用 data.frames df,因为那是函数的名称。)
  • 来吧!!我意识到,我理解我是一个新手,但还不错。我用自己的名字运行它。赶紧从上面复制粘贴。另外,如果那是错误,我就不会得到我得到的错误
  • * 抱怨 DF$change[DF[,63] == "C"] 不是数字。这不应该是这种情况,因为which 返回整数。调查为什么 DF$change 不是数字。
  • 绝对是数字。会不会是因为有时候不匹配,所以给df$change = integer(0)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2018-03-31
  • 2013-10-15
  • 2014-07-27
相关资源
最近更新 更多