Как указано в предыдущем ответе @LAP, вы можете использовать terms()
из этих моделей.Однако я бы порекомендовал взглянуть на attr(..., "factors")
и attr(..., "dataClasses")
вместо того, чтобы перейти к $model
, который требует, чтобы в модели хранилось все model.frame()
.Это может или не может иметь место.В частности, при повторной подгонке нескольких моделей вы можете захотеть не сохранять фрейм модели каждый раз.
Таким образом, одной из идей будет продолжение следующих шагов:
- Проверьте, не содержит ли
attr(..., "factors")
точно один столбец, и вы можете вернуть FALSE
. - Если указан ровно один фактор, вы можете проверить соответствующий
attr(..., "dataClasses")
, если он равен "factor"
/ "ordered"
и затем верните TRUE
, в противном случае FALSE
.
R код:
one_factor <- function(object) {
f <- attr(terms(object), "factors")
if(length(f) == 0L || NCOL(f) != 1L) return(FALSE)
d <- attr(terms(object), "dataClasses")
if(d[colnames(f)] %in% c("ordered", "factor")) {
return(TRUE)
} else {
return(FALSE)
}
}
Похоже, это хорошо работает для объектов, основанных на одной части formula
.
Фиктивные данные с числовым / коэффициентом / упорядоченным trt
:
d1 <- d2 <- d3 <- data.frame(y = log(1:9), x = 1:9, trt = rep(1:3, each = 3))
d2$trt <- factor(d2$trt)
d3$trt <- ordered(d3$trt)
Различные спецификации формул:
f <- list(
y ~ 1,
y ~ x,
y ~ trt,
y ~ trt + x,
y ~ trt + offset(x),
y ~ trt + x + offset(x),
y ~ trt + offset(as.numeric(trt)),
y ~ factor(trt),
y ~ factor(trt) + offset(x),
y ~ factor(x > as.numeric(trt)),
y ~ interaction(x, trt),
y ~ 0 + trt
)
Ожидаемые результаты для d1
, d2
,и d3
, соответственно:
ok1 <- c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE)
ok2 <- c(FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE)
ok3 <- ok2
Проверки для lm
без сохранения кадра модели:
lm1 <- lapply(f, lm, data = d1, model = FALSE)
identical(sapply(lm1, one_factor), ok1)
## [1] TRUE
lm2 <- lapply(f, lm, data = d2, model = FALSE)
identical(sapply(lm2, one_factor), ok2)
## [1] TRUE
lm3 <- lapply(f, lm, data = d3, model = FALSE)
identical(sapply(lm3, one_factor), ok3)
## [1] TRUE
Проверки для survreg
(гауссовский) и coxph
.(Последний выдает много предупреждений о несовпадении, что неудивительно, учитывая фиктивную структуру данных. Проверки по-прежнему работают, как и предполагалось.)
library("survival")
d1$y <- d2$y <- d3$y <- Surv(d1$y + 0.5)
sr1 <- lapply(f, survreg, data = d1)
identical(sapply(sr1, one_factor), ok1)
## [1] TRUE
sr2 <- lapply(f, survreg, data = d2)
identical(sapply(sr2, one_factor), ok2)
## [1] TRUE
sr3 <- lapply(f, survreg, data = d3)
identical(sapply(sr3, one_factor), ok3)
## [1] TRUE
cph1 <- lapply(f, coxph, data = d1)
identical(sapply(cph1, one_factor), ok1)
## [1] TRUE
cph2 <- lapply(f, coxph, data = d2)
identical(sapply(cph2, one_factor), ok2)
## [1] TRUE
cph3 <- lapply(f, coxph, data = d3)
identical(sapply(cph3, one_factor), ok3)
## [1] TRUE
Примечание: Если у вас естьВ составных объектах Formula
на основе этой функции может произойти сбой, и базовые тесты необходимо будет адаптировать.Примерами последних могут быть модели регрессии счета (zeroinfl
, hurdle
), полиномиальный логит (mlogit
), инструментальные переменные (ivreg
), гетероскедастические модели (vglm
, betareg
, crch
)и т. д. У них могут быть такие формулы, как y ~ trt | 1
или y ~ trt | trt
или y ~ trt | x
, которые могут или не могут быть осуществимы в вашей структуре.