Ошибка только с try () или trycatch () при использовании функции взвешивания (minpack.lm :: wfct ()) для нелинейной регрессии - PullRequest
1 голос
/ 08 мая 2020

У меня есть data.frame df, как показано ниже.

y <- c(9263, 8317, 7639, 6906, 6219, 5648, 5171, 5189, 4955, 4777, 
4697, 4533, 4356, 4173, 3991, 3868, 3642, 3394, 3270, 3109, 2888, 
2837, 2864, 2781, 2719, 2708, 2717, 2657, 2525, 2346, 2388, 2312, 
2125, 2036, 2058, 1979, 2033, 2014, 1864, 1939, 1941, 1954, 1886, 
1861, 1806, 1804, 1763, 1711, 1668, 1594, 1593, 1599, 1535, 1531, 
1556, 1436, 1447, 1415, 1314, 1446, 1335, 1334, 1412, 1276, 1264, 
1269, 1217, 1165, 1191, 1239, 1233, 1172, 1054, 1165, 1101, 1101, 
1084, 1063, 1030, 1072, 1035, 1002, 1053, 1034, 996, 1010, 951, 
897, 957, 881, 910, 953, 848, 872, 895, 873, 821, 820, 897, 820, 
798, 787, 804, 835, 763, 774, 767, 784, 797, 802, 676, 749, 716, 
749, 683, 660, 711, 720, 664, 670, 677, 685, 707, 648, 641, 660, 
647, 599, 611, 645, 625, 605, 660, 572, 605, 623, 598, 601, 567, 
575, 553, 600, 566, 523, 553, 503, 556, 529, 563, 482, 536, 530, 
517, 508, 536, 476, 529, 515, 550, 533, 500, 532, 467, 467, 455, 
473, 472, 489, 474, 464, 460, 466, 474, 449, 453, 433, 455, 414, 
430, 465, 427, 404, 437, 421, 424, 399, 405, 382, 440, 428, 399, 
450, 400, 409, 427, 403, 360, 409, 343, 391, 380, 404, 339, 408, 
380, 394, 397, 411, 358, 375, 382, 350, 364, 354, 363, 366, 342, 
367, 325, 349, 355, 331, 347, 360, 371, 358, 352, 314, 332, 317, 
319, 313, 345, 321, 321, 326, 319, 344, 312, 314, 329, 320, 275, 
313, 287, 310, 274, 264, 307, 310, 292, 290, 297, 306, 300, 335, 
296, 301, 303, 296, 304, 283, 297, 273, 282, 262, 291, 258, 284, 
277, 303, 265, 259, 243, 267, 291, 256, 254, 306, 269, 270, 284, 
295, 259, 237, 267, 285, 250, 240, 248, 258, 261, 243, 239, 259, 
202, 241, 247, 236, 204, 250, 264, 221, 239, 234, 217, 232, 229, 
230, 217, 216, 208, 255, 234, 208, 236, 227, 228, 209, 253, 215, 
207, 236, 228, 210, 204, 211, 236, 214, 215, 223, 203, 186, 213, 
213, 209, 211, 207, 204, 205, 194, 198, 189, 192, 198, 190, 186, 
198, 194, 202, 176, 191, 190, 179, 219, 200, 160, 185, 205, 179, 
208, 190, 193, 196, 177, 212, 168, 174, 186, 174, 213, 160, 221, 
181, 204, 183, 162, 143, 151, 138, 187, 153, 151, 185, 176, 187, 
159, 173, 191, 172, 158, 167, 179, 172, 172, 166, 177, 162, 186, 
160, 156, 166, 155, 155, 173, 167, 148, 147, 163, 165, 158, 144, 
146, 166, 157, 146, 163, 169, 151, 147, 160, 133, 141, 163, 163, 
148, 155, 141, 147, 166, 142, 135, 150, 147, 119, 148, 156, 146, 
150, 127, 147, 152, 142, 152, 138, 138, 119, 118, 141, 152, 135, 
123, 142, 132, 126, 133, 113, 117, 99, 123, 127, 118, 129, 128, 
124, 128, 112, 127, 138, 126, 151, 112, 135, 111, 116, 118, 123, 
121, 112, 133, 135, 107, 106, 117, 125, 136, 124, 103, 120, 116, 
121, 107, 106, 102, 125, 112, 99, 117, 106, 116, 108, 126, 129, 
129, 125, 103, 87, 105, 101, 118, 123, 91, 106, 113, 114, 105, 
108, 100, 107, 116, 112, 119, 111, 101, 111, 106, 102, 104, 114, 
112, 103, 100, 108, 96, 94, 107, 89, 103, 84, 101, 103, 93, 98, 
95, 101, 117, 99, 87, 102, 99, 99, 103, 112, 96, 88, 93, 92, 
112, 88, 85, 89, 102, 95, 79, 94, 104, 96, 88, 87, 87, 81, 73, 
90, 92, 88, 93, 82, 79, 95, 93, 89, 89, 92, 80, 81, 92, 89, 92, 
81, 84, 96, 97, 92, 92, 88, 96, 78, 101, 85, 85, 78, 88, 73, 
80, 77, 76, 81, 93, 91, 72, 70, 70, 62, 103, 90, 66, 86, 74, 
76, 73, 68, 66, 65, 76, 79, 74, 86, 78, 86, 97, 80, 93, 81, 76, 
76, 65, 74, 73, 65, 75, 79, 62, 67, 81, 74, 79, 81, 74, 86, 71, 
73, 92, 86, 64, 90, 83, 70, 73, 63, 89, 80, 78, 78, 68, 78, 60, 
77, 61, 78, 68, 59, 55, 59, 73, 79, 52, 85, 55, 76, 89, 70, 71, 
71, 69, 67, 61, 68, 72, 56, 66, 71, 75, 63, 69, 62, 71, 59, 58, 
73, 59, 64, 61, 71, 68, 67, 54, 62, 65, 62, 62, 61, 59, 60, 69, 
57, 63, 67, 45, 58, 50, 70, 61, 57, 57, 72, 84, 57, 59, 50, 69, 
59, 54, 54, 52, 51, 51, 60, 69, 57, 63, 58, 54, 58, 52, 68, 56, 
59, 64, 50, 64, 75, 65, 54, 46, 61, 52, 60, 72, 39, 58, 51, 54, 
60, 56, 63, 61, 47, 67, 46, 50, 44, 56, 51, 58, 52, 45, 53, 64, 
59, 55, 37, 66, 44, 54, 40, 64, 56, 45, 58, 46, 54, 71, 48, 50, 
39, 48, 54, 50, 53, 66, 66, 51, 41, 54, 60, 51, 53, 38, 54, 62, 
51, 71, 51, 49, 49, 51, 45, 40, 32, 50, 50, 46, 47, 51, 37, 41, 
54, 57, 48, 50, 46, 48, 33, 49, 42, 57, 50, 40, 33, 61, 48, 48, 
65, 42, 46, 39, 47, 32, 47, 43, 46, 42, 35, 49, 43, 37, 39, 34, 
46, 49, 44, 45, 35, 49, 35, 37, 40, 39, 53, 57, 48, 66, 45, 38, 
38, 49, 47, 50, 54, 35, 34, 43, 49, 32, 43, 29, 48, 39, 39, 50, 
47, 41, 30, 32, 47, 43, 46, 45, 41, 43, 31, 48, 43, 41, 42, 48, 
28, 37, 33, 34, 32, 47, 39, 38, 41, 43, 39, 26, 36, 33, 41, 37, 
32, 36, 29, 39, 37, 42, 33, 34, 34, 45, 37, 40, 35, 38, 43, 36, 
36, 32, 44, 45, 37, 29, 42, 35, 29, 26, 37, 41, 33, 33, 32, 25, 
39, 49, 34, 45, 39, 48, 46, 39, 38, 43, 35, 26, 43, 31, 35, 28, 
40, 29, 40, 42, 25, 33, 37, 41, 30, 35, 32, 37, 32, 31, 32, 31, 
32, 34, 35, 26, 35, 35, 35, 34, 36, 27, 31, 40, 44, 41, 35, 27, 
28, 37, 36, 32, 31, 22, 35, 33, 32, 26, 38, 37, 37, 31, 48, 31, 
30, 23, 34, 33, 21, 34, 32, 42, 33, 26, 35, 31, 30, 31, 39, 30, 
38, 37, 26, 20, 26, 25, 23, 28, 37, 21, 24, 25, 32, 19, 46, 29, 
30, 33, 30, 44, 25, 22, 36, 34, 27, 20, 32, 30, 30, 24, 28, 27, 
32, 27, 28, 33, 19, 27, 22, 21, 39, 36, 32, 27, 23, 24, 34, 27, 
28, 39, 16, 28, 22, 31, 31, 18, 23, 32, 24, 34, 32, 31, 37, 37, 
24, 28, 30, 22, 25, 23, 26, 33, 41, 23, 21, 28, 20, 19, 32, 29, 
25, 27, 19, 25, 32, 18, 27, 25, 25, 22, 21, 34, 25, 25, 22, 31, 
23, 24, 30, 19, 24, 19, 27, 16, 21, 35, 31, 36, 22, 23, 29, 19, 
23, 31, 24, 15, 27, 26, 34, 21, 28, 29, 28, 28, 19, 25, 25, 24, 
23, 25, 29, 36, 17, 23, 19, 14, 25, 29, 30, 18, 28, 21, 27, 32, 
21, 22, 22, 31, 21, 20, 28, 25, 16, 17, 27, 30, 22, 27, 21, 19, 
21, 26, 31, 23, 21, 17, 27, 20, 20, 20, 20, 17, 24, 18, 17, 27, 
28, 27, 28, 30, 24, 19, 24, 24, 21, 19, 27)
x <- seq_along(y) - 1
df <- data.frame(x, y)

, когда я пытаюсь подогнать двухэкспоненциальную модель, используя функцию самозапуска SSbiexp с функцией взвешивания wfct от minpack.lm, я получаю желаемый результат.

Но когда я использую try или trycatch для отладки, он показывает ошибку. Как это исправить или отладить?

traceback тоже не помогает.

library(minpack.lm)

# No wfct: works fine
nls(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
    data = df)
#> Nonlinear regression model
#>   model: y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2)
#>    data: df
#>       A1     lrc1       A2     lrc2 
#> 6471.863   -2.607 1835.803   -4.940 
#>  residual sum-of-squares: 6889608
#> 
#> Number of iterations to convergence: 0 
#> Achieved convergence tolerance: 3.211e-07
nlsLM(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
      data = df)
#> Nonlinear regression model
#>   model: y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2)
#>    data: df
#>       A1     lrc1       A2     lrc2 
#> 6471.863   -2.607 1835.803   -4.940 
#>  residual sum-of-squares: 6889608
#> 
#> Number of iterations to convergence: 1 
#> Achieved convergence tolerance: 1.49e-08

# No wfct: works fine with try() or trycatch()
try(nls(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
        data = df))
#> Nonlinear regression model
#>   model: y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2)
#>    data: df
#>       A1     lrc1       A2     lrc2 
#> 6471.863   -2.607 1835.803   -4.940 
#>  residual sum-of-squares: 6889608
#> 
#> Number of iterations to convergence: 0 
#> Achieved convergence tolerance: 3.211e-07
try(nlsLM(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
          data = df))
#> Nonlinear regression model
#>   model: y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2)
#>    data: df
#>       A1     lrc1       A2     lrc2 
#> 6471.863   -2.607 1835.803   -4.940 
#>  residual sum-of-squares: 6889608
#> 
#> Number of iterations to convergence: 1 
#> Achieved convergence tolerance: 1.49e-08

# With wfct: works fine
nls(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
    data = df, weights = wfct(1/y))
#> Nonlinear regression model
#>   model: y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2)
#>    data: df
#>       A1     lrc1       A2     lrc2 
#> 5586.621   -3.363  745.447   -5.656 
#>  weighted residual sum-of-squares: 7942
nlsLM(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
      data = df, weights = wfct(1/y))
#> Nonlinear regression model
#>   model: y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2)
#>    data: df
#>       A1     lrc1       A2     lrc2 
#> 5586.680   -3.363  745.461   -5.656 
#>  weighted residual sum-of-squares: 7942

# With wfct: Throws error with try() or trycatch()
try(nls(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
        data = df, weights = wfct(1/y)))
#> Error in DATA[[i]] : subscript out of bounds
try(nlsLM(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
          data = df, weights = wfct(1/y)))
#> Error in DATA[[i]] : subscript out of bounds

1 Ответ

1 голос
/ 08 мая 2020

2 наблюдения:

  • Ваши веса не определены в глобальном окружении. Кажется, ваш пакет полагается на ленивую оценку.
weights <- wfct(1/y)
Error in DATA[[i]] : subscript out of bounds
  • Тогда я не понимаю почему, но внутренняя функция trycatch не оценивает так же
doTryCatch <- function(expr, name, parentenv, handler) {
  .Internal(.addCondHands(name, list(handler), parentenv, 
                          environment(), FALSE))
  expr
}
doTryCatch(nlsLM(y ~ SSbiexp(input = x, A1, lrc1, A2, lrc2),
                  data = df, weights = wfct(1/y)),
            name = "error",
            handler = function(e) e,
            parentenv = .GlobalEnv)
[[1]]
NULL

[[2]]
DATA[[i]]

[[3]]
function(e) e

[[4]]
[[4]][[1]]
NULL

Наконец-то мне удалось разобраться в сделке. ваша функция wfct использует sys.calls () для извлечения данных, представленных верхней функции в стеке, которая, как я думаю, ведет себя так

t1 <- function(data=1) {
  t2 <- function() {
    str(as.list(sys.calls()[[1]])[["data"]]) ## list with two components t1() and t2()
  }
  t2()
}
t1(data=1)
num 1
t1()
NULL
try(t1(data=1))
NULL

, когда первый вызов в стеке не является функция, в которую вы добавили «данные», код работать не будет. Это также не работает, если data является аргументом по умолчанию, как показано выше.

...