使用 nls 跳过数据 table 计算中的错误
Skipping errors in data table computation using nls
这个问题建立在我之前在这里问的一个问题的基础上 。
我正在使用 nls
将指数曲线拟合到多个组的数据 table 对象。并非所有数据似乎都符合指数模型,nls
有时会抛出错误,停止对剩余组的所有进一步计算。
我在下面附加了一个 MWE,尝试使用 tryCatch
跳过有问题的组,但我最终得到了所有新列的错误输出。如何跳过为有问题的组计算 nls
值?
## Example data table
DT <- data.table(
x = c(1,2,3,4,5,6,7,8,
1,2,3,4,5,6,7,8,
1,2,3,4,5,6,7,8),
y = c(15.4,16,16.4,17.7,20,23,27,35,
25.4,26,26.4,27.7,30,33,37,45,
27.4,28,28.4,29.7,32,35,39,47),
groups = c(1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3)
)
## Fit exponential curve using starting values a,b,c for each group
DT[, c("sigma", "a", "b", "c") := {
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
},
by=.(groups)]
## Modify data table to ruin nls model for group 2
set(DT, i=16L, j="y", value=3)
## Calculation works for group 1 but stops for group 2 and onwards
DT[, c("sigma", "a", "b", "c") := {
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
},
by=.(groups)]
## My poor attempt at using a tryCatch just gives NA to every column
DT[, c("sigma","a", "b", "c") := {
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- tryCatch(
{
nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
},
error=function(err){
return(NA_real_)
}
)
},
by=.(groups)]
不用标注了,评论太长了
像这样:
DT[, c("sigma", "a", "b", "c") :=
tryCatch({
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
}, error=function(e) NA_real_),
by=.(groups)]
输出:
x y groups sigma a b c
1: 1 15.4 1 0.2986243 0.5265405 0.4565363 14.56728
2: 2 16.0 1 0.2986243 0.5265405 0.4565363 14.56728
3: 3 16.4 1 0.2986243 0.5265405 0.4565363 14.56728
4: 4 17.7 1 0.2986243 0.5265405 0.4565363 14.56728
5: 5 20.0 1 0.2986243 0.5265405 0.4565363 14.56728
6: 6 23.0 1 0.2986243 0.5265405 0.4565363 14.56728
7: 7 27.0 1 0.2986243 0.5265405 0.4565363 14.56728
8: 8 35.0 1 0.2986243 0.5265405 0.4565363 14.56728
9: 1 25.4 2 NA NA NA NA
10: 2 26.0 2 NA NA NA NA
11: 3 26.4 2 NA NA NA NA
12: 4 27.7 2 NA NA NA NA
13: 5 30.0 2 NA NA NA NA
14: 6 33.0 2 NA NA NA NA
15: 7 37.0 2 NA NA NA NA
16: 8 3.0 2 NA NA NA NA
17: 1 27.4 3 0.2986243 0.5265401 0.4565364 26.56728
18: 2 28.0 3 0.2986243 0.5265401 0.4565364 26.56728
19: 3 28.4 3 0.2986243 0.5265401 0.4565364 26.56728
20: 4 29.7 3 0.2986243 0.5265401 0.4565364 26.56728
21: 5 32.0 3 0.2986243 0.5265401 0.4565364 26.56728
22: 6 35.0 3 0.2986243 0.5265401 0.4565364 26.56728
23: 7 39.0 3 0.2986243 0.5265401 0.4565364 26.56728
24: 8 47.0 3 0.2986243 0.5265401 0.4565364 26.56728
x y groups sigma a b c
这个问题建立在我之前在这里问的一个问题的基础上
我正在使用 nls
将指数曲线拟合到多个组的数据 table 对象。并非所有数据似乎都符合指数模型,nls
有时会抛出错误,停止对剩余组的所有进一步计算。
我在下面附加了一个 MWE,尝试使用 tryCatch
跳过有问题的组,但我最终得到了所有新列的错误输出。如何跳过为有问题的组计算 nls
值?
## Example data table
DT <- data.table(
x = c(1,2,3,4,5,6,7,8,
1,2,3,4,5,6,7,8,
1,2,3,4,5,6,7,8),
y = c(15.4,16,16.4,17.7,20,23,27,35,
25.4,26,26.4,27.7,30,33,37,45,
27.4,28,28.4,29.7,32,35,39,47),
groups = c(1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3)
)
## Fit exponential curve using starting values a,b,c for each group
DT[, c("sigma", "a", "b", "c") := {
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
},
by=.(groups)]
## Modify data table to ruin nls model for group 2
set(DT, i=16L, j="y", value=3)
## Calculation works for group 1 but stops for group 2 and onwards
DT[, c("sigma", "a", "b", "c") := {
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
},
by=.(groups)]
## My poor attempt at using a tryCatch just gives NA to every column
DT[, c("sigma","a", "b", "c") := {
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- tryCatch(
{
nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
},
error=function(err){
return(NA_real_)
}
)
},
by=.(groups)]
不用标注了,评论太长了
像这样:
DT[, c("sigma", "a", "b", "c") :=
tryCatch({
c.0 <- min(y) * 0.5
model.0 <- lm(log(y - c.0) ~ x, data=.SD)
start <- list(a=exp(coef(model.0)[1]), b=coef(model.0)[2], c=c.0)
model <- nls(y ~ a * exp(b * x) + c,
data=.SD,
start=start,
control=nls.control(maxiter=500))
c(.(sigma=summary(model)$sigma), as.list(coef(model)))
}, error=function(e) NA_real_),
by=.(groups)]
输出:
x y groups sigma a b c
1: 1 15.4 1 0.2986243 0.5265405 0.4565363 14.56728
2: 2 16.0 1 0.2986243 0.5265405 0.4565363 14.56728
3: 3 16.4 1 0.2986243 0.5265405 0.4565363 14.56728
4: 4 17.7 1 0.2986243 0.5265405 0.4565363 14.56728
5: 5 20.0 1 0.2986243 0.5265405 0.4565363 14.56728
6: 6 23.0 1 0.2986243 0.5265405 0.4565363 14.56728
7: 7 27.0 1 0.2986243 0.5265405 0.4565363 14.56728
8: 8 35.0 1 0.2986243 0.5265405 0.4565363 14.56728
9: 1 25.4 2 NA NA NA NA
10: 2 26.0 2 NA NA NA NA
11: 3 26.4 2 NA NA NA NA
12: 4 27.7 2 NA NA NA NA
13: 5 30.0 2 NA NA NA NA
14: 6 33.0 2 NA NA NA NA
15: 7 37.0 2 NA NA NA NA
16: 8 3.0 2 NA NA NA NA
17: 1 27.4 3 0.2986243 0.5265401 0.4565364 26.56728
18: 2 28.0 3 0.2986243 0.5265401 0.4565364 26.56728
19: 3 28.4 3 0.2986243 0.5265401 0.4565364 26.56728
20: 4 29.7 3 0.2986243 0.5265401 0.4565364 26.56728
21: 5 32.0 3 0.2986243 0.5265401 0.4565364 26.56728
22: 6 35.0 3 0.2986243 0.5265401 0.4565364 26.56728
23: 7 39.0 3 0.2986243 0.5265401 0.4565364 26.56728
24: 8 47.0 3 0.2986243 0.5265401 0.4565364 26.56728
x y groups sigma a b c