提问人:Michael 提问时间:11/6/2023 最后编辑:Michael 更新时间:11/6/2023 访问量:53
是否有 R 函数可以强制始终将两个变量添加或删除在一起?
Is there an R function that I can force two variables always to be added or removed together?
问:
我一直在包中使用来执行模型选择。我希望模型中的两个自变量始终在逐步选择(向前和向后方向)中一起添加或删除。stepAIC
MASS
这是我的代码:
full.model <- glm(formula=Hospital ~ A + B + C + D1 + D2, family="binomial", data=data)
MASS::stepAIC(full.model, scope = list(upper = full.model, lower = Hospital ~ A),
direction = "both", trace = 1)
理想情况下,我希望 &(两者都是数值变量)总是一起添加或删除,但在我看来,stepAIC 没有这种灵活性。任何人都可以使用或其他 R 函数来了解如何实现这一点吗?非常感谢!D1
D2
stepAIC
答:
1赞
jpsmith
11/6/2023
#1
我不知道是否有参数可以容纳此功能,但您可以手动自己执行此操作。MASS::stepAIC
假设您有以下数据:
set.seed(123)
n <- 1e3
data <- data.frame(hospital = sample(0:1, n, replace = TRUE),
A = as.factor(sample(LETTERS, n, replace = TRUE)),
B = as.factor(sample(c("Apples", "Oranges", "Grapes", "Bananas"), n, replace = TRUE)),
C = as.factor(sample(c("planes","trains", "automobiles"), n, replace = TRUE)),
D1 = runif(n),
D2 = runif(n))
您可以使用以下命令生成预测变量的所有组合的列表,这些变量同时包含两者或不包含任何变量,并使用:D1
D2
# get all possible combinations
all_list <- do.call(c, lapply(seq_along(names(data)[-1]), combn, x = names(data[-1]), simplify = FALSE))
# keep only those with either both or no `D1` and `D2`
keeps <- lapply(all_list, \(x) sum((x %in% c("D1", "D2"))) != 1)
keeps_list <- all_list[unlist(keeps)]
如果运行,您将看到它包含所有带有 / 约束的排列的列名(出于空间考虑,此处不这样做)。print(keeps_list)
D1
D2
获得此列表后,可以使用以下方法遍历列表,将它们粘贴到公式中,运行模型并输出 AIC:lapply
formula_list <- lapply(keeps_list, \(x) paste0("hospital ~ ", paste(x, collapse = " + ")))
# Contains all model information
full_models <- lapply(formula_list,\(x) glm(x, family = "binomial", data = data))
其中包含所有各种组合的所有模型信息。full_model
glm()
如果要获取用于模型比较的 AIC 信息:
# extracts and organizes AIC for comparison
aic_models <- do.call(rbind, lapply(full_models, \(x) summary(x)$aic))
aic_models <- data.frame(aic_models)
rownames(aic_models) <- lapply(keeps_list, paste, collapse = "-")
# aic_models
# A 1403.604
# B 1392.457
# C 1390.975
# A-B 1408.608
# A-C 1407.239
# B-C 1395.990
# D1-D2 1389.446
# A-B-C 1412.184
# A-D1-D2 1405.016
# B-D1-D2 1394.588
# C-D1-D2 1392.992
# A-B-D1-D2 1410.132
# A-C-D1-D2 1408.626
# B-C-D1-D2 1398.091
# A-B-C-D1-D2 1413.687
然后,如果需要,您可以将它们与完整模型 () 进行比较,并确定具有最低 AIC () 的参数组合:diff
best
aic_models[,"diff"] <- aic_models[,1] - aic_models[nrow(aic_models),1]
aic_models[,"best"] <- aic_models$aic_models == min(aic_models$aic_models)
# aic_models diff best
# A 1419.566 -6.5183258 FALSE
# B 1392.836 -33.2485780 FALSE
# C 1388.043 -38.0417237 TRUE
# A-B 1424.729 -1.3556720 FALSE
# A-C 1418.896 -7.1890668 FALSE
# B-C 1392.839 -33.2454109 FALSE
# D1-D2 1390.085 -35.9994857 FALSE
# A-B-C 1424.130 -1.9541680 FALSE
# A-D1-D2 1421.337 -4.7478673 FALSE
# B-D1-D2 1394.965 -31.1196409 FALSE
# C-D1-D2 1389.972 -36.1126197 FALSE
# A-B-D1-D2 1426.671 0.5868186 FALSE
# A-C-D1-D2 1420.708 -5.3769971 FALSE
# B-C-D1-D2 1394.934 -31.1503318 FALSE
# A-B-C-D1-D2 1426.085 0.0000000 FALSE
我知道这需要一些工作,但这应该让你开始!
评论
1赞
Michael
11/8/2023
这正是我所需要的。感谢您提供详细的答案!
评论
D1
D2
D12
D12
D1
D2
D1
D2