Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

r - Terminating an apply-based function early (similar to break?)

I am searching for a way to terminate an apply function early on some condition. Using a for loop, something like:

FDP_HCFA = function(FaultMatrix, TestCosts, GenerateNeighbors, RandomSeed) {    
  set.seed(RandomSeed)

  ## number of tests, mind the summary column
  nT = ncol(FaultMatrix) - 1
  StartingSequence = sample(1:nT)
  BestAPFD = APFD_C(StartingSequence, FaultMatrix, TestCosts)
  BestPrioritization = StartingSequence
  MakingProgress = TRUE
  NumberOfIterations = 0
  while(MakingProgress) {
    BestPrioritizationBefore = BestPrioritization
    AllCurrentNeighbors = GenerateNeighbors(BestPrioritization)

    for(CurrentNeighbor in AllCurrentNeighbors) {
      CurrentAPFD = APFD_C(CurrentNeighbor, FaultMatrix, TestCosts)

      if(CurrentAPFD > BestAPFD) {
        BestAPFD = CurrentAPFD
        BestPrioritization = CurrentNeighbor            
        break
      }
    }

    if(length(union(list(BestPrioritizationBefore),
                    list(BestPrioritization))) == 1)
      MakingProgress = FALSE

    NumberOfIterations = NumberOfIterations + 1
  }
}

I would like to rewrite this function using some derivation of apply. In particular, terminating the evaluation of the first individual with increased fitness, thereby avoiding the cost of considering the rest of the population.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I reckon that you don't really grasp the apply family and its purpose. Contrary to the general idea, they're not the equivalent of any for-loop. One can say that most for-loops are the equivalent of an apply, but that's another matter.

Apply does exactly as it says: it applies a function on a number of similar arguments sequentially, and returns the result. Hence, by definition you cannot break out of an apply. You're not operating in the global environment any more, so in principle you cannot keep global counters, check after each execution some condition and adapt the loop. You can access the global environment and even change variables using assign or <<-, but this is pretty dangerous.

To understand the difference, don't read apply(1:3,afunc) as for(i in 1:3) afunc(i), but as

afunc(1)
afunc(2)
afunc(3)

in one (block) statement. That reflects better what you're doing exactly. An equivalent for break in an apply simply doesn't make sense, as it is more a block of code than a loop.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...