我正在寻找一种在某些条件下提前终止应用函数的方法。使用for循环,例如:
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
}
}
我想使用apply
的一些推导来重写此函数。特别是,终止对第一个人的评估,增加适应性,从而避免考虑其余人群的成本。
答案 0 :(得分:17)
我认为你并没有真正掌握apply
家族及其目的。与一般想法相反,它们不相当于任何for
- 循环。可以说大多数for
- 循环等同于apply
,但这是另一回事。
Apply
完全按照它的说法完成:它按顺序在一些类似的参数上应用一个函数,并返回结果。因此,根据定义,您无法摆脱申请。您不再在全局环境中运行,因此原则上您不能保留全局计数器,在每次执行后检查一些条件并调整循环。您可以使用assign
或<<-
访问全局环境甚至更改变量,但这非常危险。
要了解其中的区别,请不要将apply(1:3,afunc)
视为for(i in 1:3) afunc(i)
,而应将其视为
afunc(1)
afunc(2)
afunc(3)
在一个(块)语句中。这更好地反映了你正在做的事情。 break
中apply
的等价物只是没有意义,因为它更像是一个代码块而不是一个循环。
答案 1 :(得分:2)
除了让您的示例代码工作*
之外,我认为这是一个明确的情况,其中循环是正确的选择。虽然R可以将函数应用于整个变量向量[编辑:但是你必须在应用之前决定它们是什么],在这种情况下我会使用while
循环来避免运行不必要的重复的成本。警告:我知道for
循环在时序测试中与apply
进行了比较,但我没有看到while
的类似测试。查看http://cran.r-project.org/doc/manuals/R-lang.html#Control-structures上的一些选项。
while ( *statement1* ) *statement2*
答案 2 :(得分:2)
我也在寻找一种从早期开始的方法 基于apply的循环,并找到了这个帖子。
尽管有些人声称申请应该被视为 “块代码”而不是“循环”,我仍然认为它会 有可能打破它。原因是 基于应用的函数似乎执行得更快, 比for-loop快10到100倍的东西。多次 我已经在for循环中运行了简单的代码片段 超过几分钟,而申请似乎得到相同 在几秒钟内完成工作。