How to call top level from lapply loop (skip/pass)

半世苍凉 提交于 2020-01-23 17:53:26

问题


I want to create a lapply loop that if attends a certain requirement, it will stop...
as an example:

score <- 0
lapply(1:100, function(z){

    score <<- score + 1

    if(score >=10){
        break
    }
})

However, there is no stop argument as break/pass in a lapply loop.

I know this example sounds stupid. However, the original code has too many dependencies to be easily understood... My original loop removes an item from a vector an object every time, however, if there is nothing else to be removed from it can stop. I've gain at least 0.10 seconds with this in a normal loop short sized function

with normal "for loop" with skip argument

> time <- system.time({cyclopeptide_score(sequence, spectrum)})
> time
  usuário   sistema decorrido 
     6.58      0.00      6.58 

with laplly with no skip argument

> time <- system.time({cyclopeptide_score2(sequence, spectrum)})
> time
  usuário   sistema decorrido 
     6.72      0.00      6.72 

回答1:


To directly answer your question, here is an option (assuming you have some control of the code where the lapply happens, and of the function being applied):

withRestarts(
  lapply(
    1:10, 
    function(x) {
      cat(x)
      if(x > 5) invokeRestart("stopLoop")
  } ),
  stopLoop=function() message("Loop Stopped")
)

Produces:

123456
Loop Stopped

Basically, withRestarts/invokeRestart acts a little bit like a GOTO statement, which allows you to break out of the loop.

All this said, I wouldn't base any big code refactorings efforts on a 0.1 second improvement on 6.7 seconds run time.

Also, if you can do the above, you can probably just as easily turn your code into a for loop, which seems more appropriate given your desire to a) break out of the loop, b) use the <<- operator to cause side effects.



来源:https://stackoverflow.com/questions/26873844/how-to-call-top-level-from-lapply-loop-skip-pass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!