3

nls()を使用して、ロジスティックモデル(自己開始; SSlogis)を鳥の複数の個体群のデータに適合させています。私の目標は、期待される関数をデータに適合させ(各データセットの一部のみを使用)、期待値に関する分散の測定値をグラフに表示することです。次に、観測された関数を(各母集団のデータセット全体を使用して)近似およびプロットして、観測されたダイナミクスが期待値の分散内にあるかどうかを判断します。これを達成するために現在書かれている私のコードは次のとおりです。

    CE.mod = nls(CE.observed ~ SSlogis(t.CattleEgret, Asym, xmid, scal))

    with(collapse.data, plot(CE.time, CE.obs))

    CE.extrap = predict(CE.mod, data.frame(t.CattleEgret = CE.time))
    lines(CE.time, CE.extrap)

    CE.se.fit = sqrt(apply(attr(CE.extrap, "gradient"), 1, function(x) 
    sum(vcov(CE.mod)*outer(x,x))))

    matplot(CE.time, CE.extrap+outer(CE.se.fit, qnorm(c(0.5, 0.025, 0.975))),
    type = "l", lty = c(1,1,1), ylab = "Abundance (# per party hour)",
    xlab = "Time (year)", main = "Cattle Egret Collapse Analysis", 
    pch = 15, font.lab = 2, font.axis = 2, cex = 4, cex.lab = 1.5, 
    cex.axis = 2, cex.main = 2, frame.plot = FALSE, lwd = 4, 10)

    with(collapse.data, matpoints(CE.time, CE.obs, pch = 15, cex = 3))
    lines(CE.time, predict(nls(CE.obs ~ SSlogis(log(CE.time), 
    Asym, xmid, scal))), lty = 3, lwd = 4)

ここで(「collapse.data」ファイルから):

    t.CattleEgret = c(1:20)
    CE.time = c(1:45)
    CE.obs = c(0.3061324, 0.0000100, 0.2361211, 0.5058240, 2.0685032, 2.1944544, 
               4.2689494, 4.9508297, 3.1334720, 3.6570752, 5.6753381, 10.9133183,
               5.4518257, 20.4166979, 15.9741054, 19.0970426, 13.7559959, 14.1358153, 
               15.9986416, 29.6762828, 10.3760667, 8.4284488, 6.1060359, 3.7099982, 
               3.3584060, 2.5981386, 2.5697082, 2.8091952, 5.5487979, 1.6505442,
               2.2696972, 2.1835692, 3.6747876, 4.8307886, 3.5019731, 2.8397137,
               1.8605288, 11.1848738, 2.6268683, 4.1215127, 2.3996210, 2.6569938, 
               2.1987387, 3.0267252, 2.4420927)
    CE.observed = c(0.3061324, 0.0000100, 0.2361211, 0.5058240, 2.0685032, 2.1944544, 
               4.2689494, 4.9508297, 3.1334720, 3.6570752, 5.6753381, 10.9133183,
               5.4518257, 20.4166979, 15.9741054, 19.0970426, 13.7559959, 14.1358153, 
               15.9986416, 29.6762828)

そのコードは正常に機能し、次のような図を生成します。

アマサギ崩壊分析

ただし、コードの最終行から「log()」を削除して、次のように記述した場合は、次のようになります。

    lines(CE.time, predict(nls(CE.obs ~ SSlogis(CE.time, 
    Asym, xmid, scal))), lty = 3, lwd = 4),

線はプロットされず、次のエラーが発生します。

    Error in nls(y ~ 1/(1 + exp((xmid - x)/scal)), data = xy, start = list(xmid = 
    aux[1L],  : step factor 0.000488281 reduced below 'minFactor' of 0.000976562

nls.controlsをいじって、「minFactor」の値を変更しても、変更することはできません。また、一部の母集団のmod(##。mod部分)を定義する最初の行の後にこのエラーメッセージが表示されます。

また、一部の母集団では、これを報告するコードの最後の行の後にエラーメッセージが表示されます。

    Error in qr.solve(QR.B, cc) : singular matrix 'a' in solve

データを自然対数変換することの合理化は考えられません。predict()とSSlogis()を許可するようにデータを変更した(この場合は任意にログに記録した)と仮定します。正しく機能するように機能しますが、理由はわかりません。私はそのような問題に対するどのフォーラムでも適切な答えを見つけることができませんでした。どんな助けでも大歓迎です。

*更新:Roland(下記)が推奨するようにnlsLM関数を実装しようとしました。それは確かに、紛らわしいlog()の使用でコードの部分をクリーンアップします:

    lines(CE.time, predict(nlsLM(CE.obs ~ Asym/(1 + exp((xmid - CE.time)/scal)), start 
    = list(Asym = max(CE.obs), xmid = popsizetime[1], scal = 1), control = 
    nls.lm.control(maxiter = 1000))

ただし、他の母集団の場合、最初のモデル仕様で上記と同じエラーメッセージが表示されます。

    ChMa.mod = nls(ChMa.observed ~ SSlogis(t.ChestnutMannikin, Asym, xmid, scal))

    Error in nls(y ~ 1/(1 + exp((xmid - x)/scal)), data = xy, start = list(xmid = 
    aux[1L],  : step factor 0.000488281 reduced below 'minFactor' of 0.000976562

切り替え:

    ChMa.mod = nlsLM(ChMa.observed ~ Asym/(1 + exp((xmid - t.ChestnutMannikin)/
scal)), start = list(Asym = max(ChMa.obs), xmid = popsizetime[2], 
scal = 1), control = nls.lm.control(maxiter = 1000))

どこ

    ChMa.observed = c(4.02785074, 0.33847154, 0.99029776, 2.86516540, 0.59588068, 
    0.01334333, 2.07693362, 0.62485994, 3.48979515, 3.67785202, 20.84180181)
    t.ChestnutMannikin = c(1:11)
    popsizetime[2] = 11

このスイッチはエラーメッセージを回避しますが、nlsLMは関数を評価しますが、勾配は評価しません。勾配の評価がないと、se.fitコードを使用できないため、プロットの分散の推定値を取得できません。

4

1 に答える 1

3

問題の答えを見つけました。nlsLMで回帰している関数の勾配を生成するモデルのコンポーネントを追加する必要があります。

    log.model = function(t.RedventedBulbul, Asym, xmid, scal) {
            numericDeriv(quote(Asym/(1 + exp((xmid - t.RedventedBulbul)/scal))),
            c("Asym", "xmid", "scal"), parent.frame())
    }
于 2013-01-17T02:45:43.983 に答える