Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add normal and wald types #648

Merged
merged 69 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
a3da984
add normal and wald types
strengejacke Sep 25, 2022
a197b1d
add more type options
strengejacke Sep 25, 2022
dff4c9c
news, descripton
strengejacke Sep 25, 2022
5d6df5d
add tests
strengejacke Sep 25, 2022
3f72ab6
add more tests
strengejacke Sep 25, 2022
16eac8f
fix typo
strengejacke Sep 25, 2022
bfe55ac
Update R/get_df.R
strengejacke Sep 25, 2022
52247e3
typo
strengejacke Sep 25, 2022
801a1b4
Merge branch 'get_df_typey' of https://github.com/easystats/insight i…
strengejacke Sep 25, 2022
aaa8a05
use correct arg name
strengejacke Sep 25, 2022
2fc815b
more type -> method
strengejacke Sep 25, 2022
7cf5864
add more tests
strengejacke Sep 25, 2022
ef39651
add test glm.nb
strengejacke Sep 25, 2022
08946ae
fix test
strengejacke Sep 25, 2022
5fc2d50
get_df is enough, we just need methods for residual df
strengejacke Sep 25, 2022
6ed28fa
fix tests
strengejacke Sep 25, 2022
edfb0df
less verbose, fix some tests
strengejacke Sep 25, 2022
87c0927
fix satterthwaite and KR df
strengejacke Sep 25, 2022
f374992
docs
strengejacke Sep 25, 2022
bc5352b
simplify, more consistent
strengejacke Sep 25, 2022
e519372
add pkg to suggest
strengejacke Sep 25, 2022
71ace44
simplify tests
strengejacke Sep 25, 2022
cda0a29
add ml1-df
strengejacke Sep 25, 2022
93bdeec
fix
strengejacke Sep 25, 2022
38177e7
code style
strengejacke Sep 25, 2022
e04afa3
fix test
strengejacke Sep 25, 2022
dde16db
fix test
strengejacke Sep 25, 2022
611b75c
test
strengejacke Sep 25, 2022
c1ef952
test
strengejacke Sep 25, 2022
cc3d29e
fix lme4 KR
strengejacke Sep 25, 2022
decfaa9
test
strengejacke Sep 25, 2022
dcba1f0
test
strengejacke Sep 25, 2022
b45827a
code style
strengejacke Sep 25, 2022
fa45fd0
style
strengejacke Sep 25, 2022
75abef7
docs, add betwithin-df
strengejacke Sep 25, 2022
5e5752d
betwithin also for mermod
strengejacke Sep 25, 2022
ed9bc25
Merge branch 'main' into get_df_typey
strengejacke Sep 26, 2022
8018ba8
fix tests
strengejacke Sep 26, 2022
d851832
update docs, default to wald
strengejacke Sep 26, 2022
a6b082e
docs
strengejacke Sep 26, 2022
3b6c760
no longer test against parameters::dof
strengejacke Sep 26, 2022
70e5704
consistent spelling
strengejacke Sep 26, 2022
1c1e1ce
typo
strengejacke Sep 26, 2022
17a7c57
minor
strengejacke Sep 26, 2022
e6c969a
fix test issues
strengejacke Sep 26, 2022
d98930e
fix
strengejacke Sep 26, 2022
2d0344c
no need for "dots"
strengejacke Sep 26, 2022
bd96b83
minor, docs
strengejacke Sep 26, 2022
12717a1
comment
strengejacke Sep 26, 2022
fb7cb28
fix test issues
strengejacke Sep 26, 2022
995d6d9
test against pbkrtest
strengejacke Sep 26, 2022
57806f3
fix test
strengejacke Sep 26, 2022
8f2aeb2
fix test issues
strengejacke Sep 26, 2022
321a1e5
outcomment test for now
strengejacke Sep 26, 2022
99d9c2e
outcomment test
strengejacke Sep 26, 2022
6abada1
take chi2 into account
strengejacke Sep 26, 2022
f946c84
fix
strengejacke Sep 26, 2022
cc4907e
fix fixest-df
strengejacke Sep 26, 2022
09b5ea8
minor
strengejacke Sep 26, 2022
0f7b999
Merge branch 'main' into get_df_typey
strengejacke Sep 26, 2022
d793720
test
strengejacke Sep 26, 2022
2cf5551
now captured by default
strengejacke Sep 26, 2022
8781783
update namespace
strengejacke Sep 26, 2022
08258f7
...
strengejacke Sep 26, 2022
e671fe5
dof.gls
strengejacke Sep 26, 2022
8917a46
n_parameters for gls
strengejacke Sep 26, 2022
a997519
add tests
strengejacke Sep 26, 2022
39da400
fix test
strengejacke Sep 26, 2022
f49ac27
fix test
strengejacke Sep 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: insight
Title: Easy Access to Model Information for Various Model Objects
Version: 0.18.4.4
Version: 0.18.4.5
Authors@R:
c(person(given = "Daniel",
family = "Lüdecke",
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
refer to particular effectsizes (like Phi, Omega or Epsilon) include the related unicode-character instead of the written name. This only works on Windows for
R >= 4.2, and on OS X or Linux for R >= 4.0.

* `get_df()` gets more `type` options to return different type of degrees of
freedom (namely, `"wald"` and `"normal"`).

## Bug fixes

* Fixed issue with column alignment in `export_table()` when the data frame
Expand Down
130 changes: 98 additions & 32 deletions R/get_df.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,21 @@
#' from regression models.
#'
#' @param x A statistical model.
#' @param type Can be `"residual"`, `"model"` or `"analytical"`. `"residual"`
#' tries to extract residual degrees of freedoms. If residual degrees of freedom
#' could not be extracted, returns analytical degrees of freedom, i.e. `n-k`
#' (number of observations minus number of parameters). `"model"` returns
#' model-based degrees of freedom, i.e. the number of (estimated) parameters.
#' @param type Can be `"residual"`, `"wald"`, `"normal"`, `"analytical"`, or
#' `"model"`.
#'
#' - `"residual"` tries to extract residual degrees of freedoms. If residual
#' degrees of freedom could not be extracted, returns analytical degrees of
#' freedom, i.e. `n-k` (number of observations minus number of parameters).
#' - `"wald"` for models with z-statistic, returns `"Inf"`. Else, tries to
#' extract residual degrees of freedoms. If residual degrees of freedom could
#' not be extracted, returns `"Inf"`.
strengejacke marked this conversation as resolved.
Show resolved Hide resolved
#' - `"analytical"` returns analytical degrees of freedom, i.e. `n-k`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between residual and analytical? They sound the same to me from this description

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

analytical is always n_obs() - n_param() (n-k). not sure if which cases this may differ from residual df?

#' (number of observations minus number of parameters).
#' - `"normal"` always returns `"Inf"`.
#' - `"model"` returns model-based degrees of freedom, i.e. the number of
#' (estimated) parameters.
#'
#' @param verbose Toggle warnings.
#' @param ... Currently not used.
#'
Expand All @@ -26,13 +36,23 @@ get_df <- function(x, ...) {
#' @rdname get_df
#' @export
get_df.default <- function(x, type = "residual", verbose = TRUE, ...) {
type <- match.arg(tolower(type), choices = c("residual", "model", "analytical"))
type <- match.arg(tolower(type), choices = c("residual", "model", "analytical", "wald", "normal"))

if (type == "residual") {
if (type == "normal") {
return(Inf)
} else if (type == "residual") {
dof <- .degrees_of_freedom_residual(x, verbose = verbose)
if (is.null(dof) || all(is.infinite(dof)) || anyNA(dof)) {
dof <- .degrees_of_freedom_analytical(x)
}
} else if (type == "wald") {
if (find_statistic(x) == "z-statistic") {
return(Inf)
}
dof <- .degrees_of_freedom_residual(x, verbose = verbose)
if (is.null(dof) || all(is.infinite(dof)) || anyNA(dof)) {
return(Inf)
}
} else if (type == "analytical") {
dof <- .degrees_of_freedom_analytical(x)
} else {
Expand All @@ -59,9 +79,11 @@ get_df.model_fit <- function(x, type = "residual", verbose = TRUE, ...) {

#' @export
get_df.ivFixed <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
as.vector(x$df)
}
Expand All @@ -73,15 +95,17 @@ get_df.ivprobit <- get_df.ivFixed

#' @export
get_df.fixest <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
if (type == "residual") {
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
if (type %n% c("residual", "wald")) {
s <- summary(x)
vcov_scaled <- s$cov.scaled
if (is.null(vcov_scaled)) {
s$nobs - s$nparams
} else {
max(s$nobs - attr(vcov_scaled, "dof.K"), 1)
}
} else if (type == "normal") {
return(Inf)
} else {
.model_df(x)
}
Expand All @@ -90,9 +114,12 @@ get_df.fixest <- function(x, type = "residual", ...) {

#' @export
get_df.multinom <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
stat <- find_statistic(x)
if (type == "model") {
.model_df(x)
} else if (type == "normal" || (type == "wald" && stat == "z-statistic")) {
return(Inf)
} else {
n_obs(x) - x$edf
}
Expand All @@ -104,9 +131,11 @@ get_df.nnet <- get_df.multinom

#' @export
get_df.summary.lm <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
x$fstatistic[3]
}
Expand Down Expand Up @@ -146,9 +175,11 @@ get_df.coeftest <- function(x, ...) {

#' @export
get_df.lqmm <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
cs <- summary(x)
tryCatch(
Expand All @@ -173,9 +204,12 @@ get_df.lqm <- get_df.lqmm

#' @export
get_df.cgam <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
stat <- find_statistic(x)
if (type == "model") {
.model_df(x)
} else if (type == "normal" || (type == "wald" && stat == "z-statistic")) {
return(Inf)
} else {
# x$resid_df_obs
# new in cgam 1.18
Expand All @@ -186,9 +220,12 @@ get_df.cgam <- function(x, type = "residual", ...) {

#' @export
get_df.cgamm <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
stat <- find_statistic(x)
if (type == "model") {
.model_df(x)
} else if (type == "normal" || (type == "wald" && stat == "z-statistic")) {
return(Inf)
} else {
x$resid_df_obs
}
Expand All @@ -197,9 +234,11 @@ get_df.cgamm <- function(x, type = "residual", ...) {

#' @export
get_df.glht <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
x$df
}
Expand All @@ -216,8 +255,11 @@ get_df.BBreg <- get_df.glht

#' @export
get_df.rlm <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
if (type == "residual") {
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
stat <- find_statistic(x)
if (type == "normal" || (type == "wald" && stat == "z-statistic")) {
return(Inf)
} else if (type %in% c("residual", "wald")) {
.degrees_of_freedom_analytical(x)
} else {
.model_df(x)
Expand Down Expand Up @@ -253,7 +295,7 @@ get_df.truncreg <- get_df.rlm

#' @export
get_df.rq <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "residual") {
tryCatch(
{
Expand All @@ -265,6 +307,8 @@ get_df.rq <- function(x, type = "residual", ...) {
NULL
}
)
} else if (type == "normal") {
return(Inf)
} else {
.model_df(x)
}
Expand All @@ -273,9 +317,11 @@ get_df.rq <- function(x, type = "residual", ...) {

#' @export
get_df.rqss <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "residual") {
n_obs(x) - x$edf
} else if (type == "normal") {
return(Inf)
} else {
.model_df(x)
}
Expand All @@ -284,9 +330,11 @@ get_df.rqss <- function(x, type = "residual", ...) {

#' @export
get_df.bfsl <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "residual") {
x$df.residual
} else if (type == "normal") {
return(Inf)
} else {
.model_df(x)
}
Expand All @@ -295,9 +343,11 @@ get_df.bfsl <- function(x, type = "residual", ...) {

#' @export
get_df.plm <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "residual") {
x$df.residual
} else if (type == "normal") {
return(Inf)
} else {
.model_df(x)
}
Expand All @@ -306,9 +356,11 @@ get_df.plm <- function(x, type = "residual", ...) {

#' @export
get_df.selection <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
s <- summary(x)
s$param$df
Expand All @@ -319,7 +371,7 @@ get_df.selection <- function(x, type = "residual", ...) {
#' @export
get_df.lmerMod <- function(x, type = "residual", ...) {
dots <- list(...)
type <- match.arg(tolower(type), choices = c("residual", "model", "analytical", "satterthwaite", "kenward", "kenward-roger"))
type <- match.arg(tolower(type), choices = c("residual", "model", "analytical", "satterthwaite", "kenward", "kenward-roger", "normal", "wald"))
# fix name for lmerTest
if (type == "kenward") {
type <- "kenward-roger"
Expand Down Expand Up @@ -350,11 +402,13 @@ get_df.lmerModTest <- get_df.lmerMod

#' @export
get_df.logitor <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal", "wald"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
get_df.default(x$fit, ...)
get_df.default(x$fit, type = type, ...)
}
}

Expand Down Expand Up @@ -393,9 +447,11 @@ get_df.betamfx <- get_df.logitor

#' @export
get_df.merModList <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
s <- suppressWarnings(summary(x))
s$fe$df
Expand All @@ -407,16 +463,18 @@ get_df.merModList <- function(x, type = "residual", ...) {
get_df.mira <- function(x, type = "residual", ...) {
# installed?
check_if_installed("mice")
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
get_df(mice::pool(x), type, ...)
}


#' @export
get_df.mipo <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
as.vector(summary(x)$df)
}
Expand All @@ -425,9 +483,11 @@ get_df.mipo <- function(x, type = "residual", ...) {

#' @export
get_df.vgam <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
params <- get_parameters(x)
out <- stats::setNames(rep(NA, nrow(params)), params$Parameter)
Expand All @@ -439,9 +499,11 @@ get_df.vgam <- function(x, type = "residual", ...) {

#' @export
get_df.rqs <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "model") {
.model_df(x)
} else if (type == "normal") {
return(Inf)
} else {
tryCatch(
{
Expand All @@ -459,7 +521,11 @@ get_df.rqs <- function(x, type = "residual", ...) {

#' @export
get_df.systemfit <- function(x, type = "residual", ...) {
type <- match.arg(tolower(type), choices = c("residual", "model"))
type <- match.arg(tolower(type), choices = c("residual", "model", "normal"))
if (type == "normal") {
return(Inf)
}

df <- c()
s <- summary(x)$eq
params <- find_parameters(x)
Expand Down
20 changes: 15 additions & 5 deletions man/get_df.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading