我正在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)
答案 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=