2017-01-18 14 views
-1

私は生産性/ haという条件の下で、セット全体生産(prodTarget)を生産するのに必要な所与の領域の中で最も小さい割合を見つけるRのwhileループを作成しました最大の生産性を上回らない。R:Whileループが不明確な数値を出力する

whileループ自体はうまく動作し、まさにそれがやろうとしていることですが、問題はループの後で最小の割合(whileループによって与えられたもの)から1になるまで発生します。 whileループで見つかった最小の割合が1の場合、seq()コマンドはエラーを返します(下のコードの最初のバージョン)。ただし、seq(1,1,0.1)は手動で正常に動作し、期待どおり1を返します。

conservation_Yield<-8.4 # set minimal Yield/ha 
max_current_Yield<-173.1 # the maximum observed Yield/ha 
Area <- 226.02 # the area in ha 

min_target <- conservation_Yield*Area 
max_target <- max_current_Yield*Area 
prodTargets <- seq(min_target,max_target,Area) # set a range of production targets 

# Start loop over all production targets (166 in total, the last two loops are the problem) 
for (i in 165: length(prodTargets)){ 

    currentTarget <- prodTargets[i] 
    # Define the range of proportion managed land from the minimum feasable (given the target and maximum productivity) 
    #   to maximum possible 

    min_proportion <- 0 # to find the minimum feasable, we set the proportion to zero 
    control_Yield <- max_current_Yield*10 # set to arbitrary higher value as max possible yield 

    while (control_Yield > max_current_Yield){ 
    min_proportion <- min_proportion+0.01 # increase the proportion of managed land 
    rest_productivity <- currentTarget-conservation_Yield*Area*(1-min_proportion) 
    control_Yield <- rest_productivity/(Area*min_proportion) 
    } 

    max_proportion <- 1 # the maximum possible proportion is always 1 

    # First version: works fine for all loops except where min_proportion has to be 1 as well 
    landsparing_scenarios <- seq(min_proportion,max_proportion,0.01) # returns an error 

    # Second version: Check if min_proportion == 1 and create a vector of 1 manually 
    if (min_proportion == 1) { # returns FALSE even though min_proportion is 1 
    landsparing_scenarios <- 1 
    } else { 
    landsparing_scenarios <- seq(min_proportion,max_proportion,0.01) 

    } 

    # Third version: Check if min_proportion > 0.99 and create a vector of 1 manually 
    if (min_proportion > 0.99) { 
    landsparing_scenarios <- 1 
    } else { 
    landsparing_scenarios <- seq(min_proportion,max_proportion,0.01) 

    } 

} 

if-else節を追加して、最小比率が1(2番目のバージョン)に等しいかどうかを確認しました。さて、min_proportionはコンソールに入力すると数値1を返しますが、コマンドmin_proportion == 1はFALSEを返します。 変数が1のように見え、論理演算子が不一致になる可能性はありますか?

+0

おそらく、これは丸めによるものです。 print(seq(0、1、by = 0.01)、digits = 16)の出力を考えてみましょう。あなたは '=='ではなく '?all.equal'を使うことを検討するかもしれません。 – lmo

+0

@lmo:すべての桁を見ると良いと指摘してくれてありがとう。また、丸め誤差があると思われましたが、数字に0.01を加えた後に見つかるとは思いませんでした。 –

答えて

0

whileループでは、各繰り返しで0.01の値が最小割合に追加されました。 min_proportionの出力は、ループの最後のステップがmin_proportion = 0.99+0.01であることを示唆しましたが、結果の数値は16桁目で1より大きかった。 でシーケンスを作成しようとすると、実際にはmin_proportionが1より大きい1.000000000000001であるため、エラーが発生しました。このシーケンスは不可能です。これは、​​テストがFALSEを返したが、テストmin_proportion > 0.99TRUEを返す理由でもあります。

可能な解決策の1つは、変数min_proportionをwhileループの後の2桁に丸めることです。もう1つの可能性(@lmoで指摘されているように)は、all.equal(min_proportion, 1)という関数を使用して、==よりも厳密になります。

関連する問題