将值分配给不带引号的列表项,以便它可以用作参数值

Assign value to list item without quotes so it can be used as parameter value

我想将数值分配给列表的字符元素,但分配给该元素的未引用版本,以便我可以在模型公式中使用它。

假设我有一个完全指定的模型公式,我将在 nls 函数中使用它:

m.form <- y ~ b0 + b1*x1 + b2*x2

(我知道我的示例是线性的,但这并不重要)。我还有一个参数名称列表和每个参数的一些起始值:

params <- c("b0","b1","b2") 
startvals <- list(b0=1, b1=1, b2=-1)

然后我想为 params 中的参数赋值,这样我就可以估计模型的受限版本,假设强制 b1==0。当然,我想通过引用向量 params 中的参数来做到这一点(因为我将对具有更多变量和参数的模型进行循环,并在每次循环迭代时使用给定的限制来估计模型)。

所以我想做这样的事情:

params[2] <- 0
summary(nls(m.form,data,startvals[-2])

我试图用数字 0 替换公式中的参数名称,然后从 startvals 中删除该参数的起始值,因为该参数不再出现在模型中(很可能不是最好的方法做这个!)。以上不起作用,但如果我使用“b1 <- 0”而不是“params[1] <- 0”行,它确实可以按预期工作。但是我会遍历模型中的所有参数,所以我不想每次都写出实际的参数名称。谢谢

编辑 1

所以为了更清楚,我需要能够通过引用 params 向量的元素来施加限制,因为我最终要循环遍历,每次估计具有不同限制的模型。所以,例如也许在第一个循环迭代中我强加了 params[2]=0,但在接下来,也许是 params[3]=0.5.

您可以编写一个函数来进行替换:

m.form <- y ~ b0 + b1*x1 + b2*x2

restrict <- function(form, restrictions){
  restrictions <- setNames(as.character(restrictions), names(restrictions))
  form <- stringr::str_replace_all(deparse(form), restrictions)
  as.formula(form)
}

params <- c("b0","b1","b2") 
startvals <- list(b0=1, b1=1, b2=-1)
summary(nls(restrict(m.form, c(b1 = 0)),data,startvals[-2]))

您可以限制 1 个以上的参数:

summary(nls(restrict(m.form, c(b1 = 0, b0 = 1)),data,startvals[3]))

1) 通过定义值并从 startvals 中移除,可以在不重写公式的情况下完成。没有使用包。

set.seed(123)
DF <- data.frame(y = rnorm(25), x1 = rnorm(25), x2 = rnorm(25))

m.form <- y ~ b0 + b1*x1 + b2*x2
startvals <- list(b0=1, b1=1, b2=-1)
b1 <- 0
nls(m.form, DF, start = startvals[-2])

给予:

Nonlinear regression model
  model: y ~ b0 + b1 * x1 + b2 * x2
   data: DF
      b0       b2 
-0.03457  0.12139 
 residual sum-of-squares: 21.18

Number of iterations to convergence: 1 
Achieved convergence tolerance: 3.722e-09

2) 或者如果您想将 b1 = 0 代入公式,则

m.form0 <- do.call("substitute", list(m.form, list(b1 = 0)))
nls(m.form0, DF, start = startvals[-2])

给予:

Nonlinear regression model
  model: y ~ b0 + 0 * x1 + b2 * x2
   data: DF
      b0       b2 
-0.03457  0.12139 
 residual sum-of-squares: 21.18

Number of iterations to convergence: 1 
Achieved convergence tolerance: 3.722e-09

已添加

如果您想根据参数索引号的非空向量 ix 和约束值的等长向量 vals 来指定这些,那么

set.seed(123)
DF <- data.frame(y = rnorm(25), x1 = rnorm(25), x2 = rnorm(25))

m.form <- y ~ b0 + b1*x1 + b2*x2
params <- c("b0", "b1", "b2")
startvals <- list(b0 = 1, b1 = 1, b2 = -1)

ix <- 2
vals <- 0
L <- setNames(list(vals), params[ix])

# 1
list2env(L, environment(m.form)) # add constraints to formula's envir
nls(m.form, DF, start = startvals[-ix])
## Nonlinear regression model
##   model: y ~ b0 + b1 * x1 + b2 * x2
## ...snip...

# 2
m.form0 <- do.call("substitute", list(m.form, L))
nls(m.form0, DF, start = startvals[-ix])
## Nonlinear regression model
##   model: y ~ b0 + 0 * x1 + b2 * x2
## ...sjip...