更新功能中的模型因子级别无法正常工作

时间:2018-07-10 20:33:26

标签: r function

我正在R中运行一些GLM模型,这些模型与我正在进行的进食试验有关。我将感兴趣的变量回归为两个预测变量:一个具有三个级别的因子和一个连续变量。我想将因子的每个级别的截距相互比较,以确定它们是否不同。为此,我编写了一个函数(在下面的可再现代码中称为“ interceptCompare”),该函数可重新调整因子并更新模型,然后保存每个模型的结果。这是我进行截距的所有成对比较的快速方法。

问题在于,当我运行该函数时,它似乎无法正确更新模型。返回的列表中的每一项都是相同的,因此应该对其进行更改,以便每一项与要比较其他级别的“(拦截)”具有不同级别的因素。我怀疑这与功能的环境有关,但我不确定。我在stackoverflow或google上找不到类似的示例。

以下是可重现的示例:

food <- as.factor(rep(c("a", "b", "c"), each = 20))
variable <- rbinom(60, 1, 0.7)
movement <- rgamma(60, 10, 2)
binomial.model <- glm(variable ~ food,
         family = "binomial")
gamma.model <- glm(movement ~ food,
               family = Gamma)
interceptCompare <- function(model, factor) {
  results <- list() # empty list to store results
  for (i in unique(factor)) {
    factor <- relevel(factor, ref = i)
    model <- update(model)
    results[[i]] <- summary(model)$coefficients[1:3, ]
  }
  results <- lapply(results, function(x) round(x, 4))
  return(results)
}

interceptCompare(binomial.model, food)
interceptCompare(gamma.model, food)

2 个答案:

答案 0 :(得分:1)

您需要添加一行以更改数据,并在更新中使用它:

interceptCompare <- function(model, factor) {
  results <- list() # empty list to store results

   s <- deparse(substitute(factor))#ADD THIS LINE

  for (i in unique(factor)) {
    factor <- relevel(factor, ref = i)
    model[["model"]][[s]] <- factor #CHANGE THE DATA IN THE MODEL
    model <- update(model,data=model[["model"]])# UPDATE THE MODEL
    results[[i]] <- summary(model)$coefficients[1:3, ]
  }
  results <- lapply(results, function(x) round(x, 4))
  return(results)
}

interceptCompare(binomial.model, food)
$a
            Estimate Std. Error z value Pr(>|z|)
(Intercept)   1.3863     0.5590  2.4799   0.0131
foodb        -0.7673     0.7296 -1.0516   0.2930
foodc        -0.2877     0.7610 -0.3780   0.7054

$b
            Estimate Std. Error z value Pr(>|z|)
(Intercept)   0.6190     0.4688  1.3205   0.1867
fooda         0.7673     0.7296  1.0516   0.2930
foodc         0.4796     0.6975  0.6876   0.4917

$c
            Estimate Std. Error z value Pr(>|z|)
(Intercept)   1.0986     0.5164  2.1275   0.0334
foodb        -0.4796     0.6975 -0.6876   0.4917
fooda         0.2877     0.7610  0.3780   0.7054


interceptCompare(gamma.model, food)
$a
            Estimate Std. Error t value Pr(>|t|)
(Intercept)   0.2246     0.0156 14.3919   0.0000
foodb        -0.0170     0.0213 -0.8022   0.4257
foodc        -0.0057     0.0218 -0.2608   0.7952

$b
            Estimate Std. Error t value Pr(>|t|)
(Intercept)   0.2076     0.0144 14.3919   0.0000
fooda         0.0170     0.0213  0.8022   0.4257
foodc         0.0114     0.0210  0.5421   0.5898

$c
            Estimate Std. Error t value Pr(>|t|)
(Intercept)   0.2189     0.0152 14.3919   0.0000
foodb        -0.0114     0.0210 -0.5421   0.5898
fooda         0.0057     0.0218  0.2608   0.7952

答案 1 :(得分:0)

在尝试从公式中换出符号时,您需要格外小心。您需要用R语言可以理解的术语来表达它。您想传递名称“ food”,而不是像现在那样传递“ food”向量中存储的值。这是一个似乎可以完成您想做的更新

interceptCompare <- function(model, factor) {
  sym <- substitute(factor)
  results <- list() # empty list to store results
  for (i in unique(factor)) {
    change <- eval(bquote(~.-.(sym)+relevel(.(sym), ref=.(i))))
    new_model <- update(model, change)
    results[[i]] <- summary(new_model)$coefficients[1:3, ]
  }
  results <- lapply(results, function(x) round(x, 4))
  return(results)
}

在这里,我们用substitute捕获了“食品”的名称。然后,我们使用bquote()来构建一个新公式,该公式将删除原始值,并使用特定参考重新调整因子变量。然后,我们将其保存到新对象中,这样就不会继续更新同一模型。对于binomial.model,它返回

$`a`
                          Estimate Std. Error z value Pr(>|z|)
(Intercept)                 0.8473     0.4879  1.7364   0.0825
relevel(food, ref = "a")b   0.0000     0.6901  0.0000   1.0000
relevel(food, ref = "a")c  -0.8473     0.6619 -1.2801   0.2005

$b
                          Estimate Std. Error z value Pr(>|z|)
(Intercept)                 0.8473     0.4879  1.7364   0.0825
relevel(food, ref = "b")a   0.0000     0.6901  0.0000   1.0000
relevel(food, ref = "b")c  -0.8473     0.6619 -1.2801   0.2005

$c
                          Estimate Std. Error z value Pr(>|z|)
(Intercept)                 0.0000     0.4472  0.0000   1.0000
relevel(food, ref = "c")a   0.8473     0.6619  1.2801   0.2005
relevel(food, ref = "c")b   0.8473     0.6619  1.2801   0.2005

您可以看到它在每次迭代中如何改变ref=