for循环内优化找不到函数
Optimize within for loop cannot find function
我有一个函数,KozakTaper
,returns 树的直径 t运行k 在给定高度 (DHT)。没有代数方法可以将原始锥度方程重新排列为给定直径(4 英寸,就我而言)的 return DHT...输入 R! (在 Windows 10 上使用 3.4.3)
我的方法是使用 for 循环迭代 DHT 的可能值(总树高的 25-100%,HT),然后使用优化选择直径最接近 return 的值4"。太糟糕了,我收到错误消息 Error in f(arg, ...) : could not find function "f"
。
这是 KozakTaper 的简短定义以及我迄今为止的最佳尝试。
KozakTaper=function(Bark,SPP,DHT,DBH,HT,Planted){
if(Bark=='ob' & SPP=='AB'){
a0_tap=1.0693567631
a1_tap=0.9975021951
a2_tap=-0.01282775
b1_tap=0.3921013594
b2_tap=-1.054622304
b3_tap=0.7758393514
b4_tap=4.1034897617
b5_tap=0.1185960455
b6_tap=-1.080697381
b7_tap=0}
else if(Bark=='ob' & SPP=='RS'){
a0_tap=0.8758
a1_tap=0.992
a2_tap=0.0633
b1_tap=0.4128
b2_tap=-0.6877
b3_tap=0.4413
b4_tap=1.1818
b5_tap=0.1131
b6_tap=-0.4356
b7_tap=0.1042}
else{
a0_tap=1.1263776728
a1_tap=0.9485083275
a2_tap=0.0371321602
b1_tap=0.7662525552
b2_tap=-0.028147685
b3_tap=0.2334044323
b4_tap=4.8569609081
b5_tap=0.0753180483
b6_tap=-0.205052535
b7_tap=0}
p = 1.3/HT
z = DHT/HT
Xi = (1 - z^(1/3))/(1 - p^(1/3))
Qi = 1 - z^(1/3)
y = (a0_tap * (DBH^a1_tap) * (HT^a2_tap)) * Xi^(b1_tap * z^4 + b2_tap * (exp(-DBH/HT)) +
b3_tap * Xi^0.1 + b4_tap * (1/DBH) + b5_tap * HT^Qi + b6_tap * Xi + b7_tap*Planted)
return(y=round(y,4))}
HT <- .3048*85 #converting from english to metric (sorry, it's forestry)
for (i in c((HT*.25):(HT+1))) {
d <- KozakTaper(Bark='ob',SPP='RS',DHT=i,DBH=2.54*19,HT=.3048*85,Planted=0)
frame <- na.omit(d)
optimize(f=abs(10.16-d), interval=frame, lower=1, upper=90,
maximum = FALSE,
tol = .Machine$double.eps^0.25)
}
最终我希望此代码遍历 csv 和 return i 以获得最佳 d,这将需要一些重新排列,但我想我应该首先让它适用于一棵树。
当我打印 d 时,我得到了多个值,因此它遍历了 i,但它在优化函数中被阻止了。
定义 frame
是我最近的策略,因为 d return 最后有一个 NaN
,但它可能不是 interval
的最佳输入。我试过 interval=c((HT*.25):(HT+1))
,在 for 循环中定义 KozakTaper,并在优化之前定义 f,但我得到了同样的错误。对我应该针对哪个部分(或其他方法)的建议表示赞赏!
-KB
阿巴拉契亚山脉俱乐部林业研究员。
缅因大学硕士
**使用后续问题进行编辑:
我现在正在尝试 运行 为 csv 的每一行编写此脚本,"Input." 该行包含 KozakTaper 的值,我用这个调用它们:
Input=read.csv...
Input$Opt=0
o <- optimize(f = function(x) abs(10.16 - KozakTaper(Bark='ob',
SPP='Input$Species',
DHT=x,
DBH=(2.54*Input$DBH),
HT=(.3048*Input$Ht),
Planted=0)),
lower=Input$Ht*.25, upper=Input$Ht+1,
maximum = FALSE, tol = .Machine$double.eps^0.25)
Input$Opt <- o$minimum
Input$Mht <- Input$Opt/.3048. # converting back to English
Input$Ht 和 Input$DBH 是数字;输入$物种是因素。
但是,我收到错误 invalid function value in 'optimize'
。无论是定义 "o" 还是只是 运行 优化,我都能理解。奇怪的是,当我不调用行中的值而是使用答案中的代码时,它告诉我 object 'HT' not found
。我有一种糟糕的感觉,这是由于我的某些 obvious/careless 错误造成的,但我没有找到关于此错误的优化帖子。如果您发现我做错了什么,您的解释将不胜感激!
我不是优化方面的专家,但我发现了三个问题:1) 您对 KozakTaper
的调用没有遍历您在循环中指定的范围。 2) KozakTaper
returns 一个数字而不是向量。 3)你没有给优化一个函数,而是一个表达式。
所以发生的事情是你没有给 optimize
任何迭代。
你只需要这个:
optimize(f = function(x) abs(10.16 - KozakTaper(Bark='ob',
SPP='RS',
DHT=x,
DBH=2.54*19,
HT=.3048*85,
Planted=0)),
lower=HT*.25, upper=HT+1,
maximum = FALSE, tol = .Machine$double.eps^0.25)
$minimum
[1] 22.67713 ##Hopefully this is the right answer
$objective
[1] 0
Optimize 现在会将 x
替换为从 lower
到 higher
,试图将差异最小化
我有一个函数,KozakTaper
,returns 树的直径 t运行k 在给定高度 (DHT)。没有代数方法可以将原始锥度方程重新排列为给定直径(4 英寸,就我而言)的 return DHT...输入 R! (在 Windows 10 上使用 3.4.3)
我的方法是使用 for 循环迭代 DHT 的可能值(总树高的 25-100%,HT),然后使用优化选择直径最接近 return 的值4"。太糟糕了,我收到错误消息 Error in f(arg, ...) : could not find function "f"
。
这是 KozakTaper 的简短定义以及我迄今为止的最佳尝试。
KozakTaper=function(Bark,SPP,DHT,DBH,HT,Planted){
if(Bark=='ob' & SPP=='AB'){
a0_tap=1.0693567631
a1_tap=0.9975021951
a2_tap=-0.01282775
b1_tap=0.3921013594
b2_tap=-1.054622304
b3_tap=0.7758393514
b4_tap=4.1034897617
b5_tap=0.1185960455
b6_tap=-1.080697381
b7_tap=0}
else if(Bark=='ob' & SPP=='RS'){
a0_tap=0.8758
a1_tap=0.992
a2_tap=0.0633
b1_tap=0.4128
b2_tap=-0.6877
b3_tap=0.4413
b4_tap=1.1818
b5_tap=0.1131
b6_tap=-0.4356
b7_tap=0.1042}
else{
a0_tap=1.1263776728
a1_tap=0.9485083275
a2_tap=0.0371321602
b1_tap=0.7662525552
b2_tap=-0.028147685
b3_tap=0.2334044323
b4_tap=4.8569609081
b5_tap=0.0753180483
b6_tap=-0.205052535
b7_tap=0}
p = 1.3/HT
z = DHT/HT
Xi = (1 - z^(1/3))/(1 - p^(1/3))
Qi = 1 - z^(1/3)
y = (a0_tap * (DBH^a1_tap) * (HT^a2_tap)) * Xi^(b1_tap * z^4 + b2_tap * (exp(-DBH/HT)) +
b3_tap * Xi^0.1 + b4_tap * (1/DBH) + b5_tap * HT^Qi + b6_tap * Xi + b7_tap*Planted)
return(y=round(y,4))}
HT <- .3048*85 #converting from english to metric (sorry, it's forestry)
for (i in c((HT*.25):(HT+1))) {
d <- KozakTaper(Bark='ob',SPP='RS',DHT=i,DBH=2.54*19,HT=.3048*85,Planted=0)
frame <- na.omit(d)
optimize(f=abs(10.16-d), interval=frame, lower=1, upper=90,
maximum = FALSE,
tol = .Machine$double.eps^0.25)
}
最终我希望此代码遍历 csv 和 return i 以获得最佳 d,这将需要一些重新排列,但我想我应该首先让它适用于一棵树。
当我打印 d 时,我得到了多个值,因此它遍历了 i,但它在优化函数中被阻止了。
定义 frame
是我最近的策略,因为 d return 最后有一个 NaN
,但它可能不是 interval
的最佳输入。我试过 interval=c((HT*.25):(HT+1))
,在 for 循环中定义 KozakTaper,并在优化之前定义 f,但我得到了同样的错误。对我应该针对哪个部分(或其他方法)的建议表示赞赏!
-KB
阿巴拉契亚山脉俱乐部林业研究员。 缅因大学硕士
**使用后续问题进行编辑: 我现在正在尝试 运行 为 csv 的每一行编写此脚本,"Input." 该行包含 KozakTaper 的值,我用这个调用它们:
Input=read.csv...
Input$Opt=0
o <- optimize(f = function(x) abs(10.16 - KozakTaper(Bark='ob',
SPP='Input$Species',
DHT=x,
DBH=(2.54*Input$DBH),
HT=(.3048*Input$Ht),
Planted=0)),
lower=Input$Ht*.25, upper=Input$Ht+1,
maximum = FALSE, tol = .Machine$double.eps^0.25)
Input$Opt <- o$minimum
Input$Mht <- Input$Opt/.3048. # converting back to English
Input$Ht 和 Input$DBH 是数字;输入$物种是因素。
但是,我收到错误 invalid function value in 'optimize'
。无论是定义 "o" 还是只是 运行 优化,我都能理解。奇怪的是,当我不调用行中的值而是使用答案中的代码时,它告诉我 object 'HT' not found
。我有一种糟糕的感觉,这是由于我的某些 obvious/careless 错误造成的,但我没有找到关于此错误的优化帖子。如果您发现我做错了什么,您的解释将不胜感激!
我不是优化方面的专家,但我发现了三个问题:1) 您对 KozakTaper
的调用没有遍历您在循环中指定的范围。 2) KozakTaper
returns 一个数字而不是向量。 3)你没有给优化一个函数,而是一个表达式。
所以发生的事情是你没有给 optimize
任何迭代。
你只需要这个:
optimize(f = function(x) abs(10.16 - KozakTaper(Bark='ob',
SPP='RS',
DHT=x,
DBH=2.54*19,
HT=.3048*85,
Planted=0)),
lower=HT*.25, upper=HT+1,
maximum = FALSE, tol = .Machine$double.eps^0.25)
$minimum
[1] 22.67713 ##Hopefully this is the right answer
$objective
[1] 0
Optimize 现在会将 x
替换为从 lower
到 higher
,试图将差异最小化