@@ -218,9 +218,9 @@ check_model.default <- function(x,
218
218
if (minfo $ is_bayesian ) {
219
219
suppressWarnings(.check_assumptions_stan(x , ... ))
220
220
} else if (minfo $ is_linear ) {
221
- suppressWarnings(.check_assumptions_linear(x , minfo , residual_type , verbose , ... ))
221
+ suppressWarnings(.check_assumptions_linear(x , minfo , check , residual_type , verbose , ... ))
222
222
} else {
223
- suppressWarnings(.check_assumptions_glm(x , minfo , residual_type , verbose , ... ))
223
+ suppressWarnings(.check_assumptions_glm(x , minfo , check , residual_type , verbose , ... ))
224
224
},
225
225
error = function (e ) {
226
226
e
@@ -237,6 +237,15 @@ check_model.default <- function(x,
237
237
)
238
238
}
239
239
240
+ # did Q-Q plot work with simulated residuals?
241
+ if (verbose && is.null(assumptions_data $ QQ ) && residual_type == " simulated" ) {
242
+ insight :: format_warning(paste0(
243
+ " Cannot simulate residuals for models of class `" ,
244
+ class(x )[1 ],
245
+ " `. Please try `check_model(..., residual_type = \" normal\" )` instead."
246
+ ))
247
+ }
248
+
240
249
# try to find sensible default for "type" argument
241
250
suggest_dots <- (minfo $ is_bernoulli || minfo $ is_count || minfo $ is_ordinal || minfo $ is_categorical || minfo $ is_multinomial ) # nolint
242
251
if (missing(type ) && suggest_dots ) {
@@ -412,26 +421,57 @@ check_model.DHARMa <- check_model.performance_simres
412
421
413
422
# compile plots for checks of linear models ------------------------
414
423
415
- .check_assumptions_linear <- function (model , model_info , residual_type = " normal" , verbose = TRUE , ... ) {
424
+ .check_assumptions_linear <- function (model , model_info , check = " all " , residual_type = " normal" , verbose = TRUE , ... ) {
416
425
dat <- list ()
417
426
418
- dat $ VIF <- .diag_vif(model , verbose = verbose )
419
- dat $ QQ <- switch (residual_type ,
420
- simulated = simulate_residuals(model , ... ),
421
- .diag_qq(model , model_info = model_info , verbose = verbose )
422
- )
423
- dat $ REQQ <- .diag_reqq(model , level = 0.95 , model_info = model_info , verbose = verbose )
424
- dat $ NORM <- .diag_norm(model , verbose = verbose )
425
- dat $ NCV <- .diag_ncv(model , verbose = verbose )
426
- dat $ HOMOGENEITY <- .diag_homogeneity(model , verbose = verbose )
427
- dat $ OUTLIERS <- .safe(check_outliers(model , method = " cook" ))
428
- if (is.null(dat $ OUTLIERS )) {
429
- threshold <- NULL
430
- } else {
431
- threshold <- attributes(dat $ OUTLIERS )$ threshold $ cook
427
+ # multicollinearity --------------
428
+ if (any(c(" all" , " vif" ) %in% check )) {
429
+ dat $ VIF <- .diag_vif(model , verbose = verbose )
430
+ }
431
+
432
+ # Q-Q plot (normality/uniformity of residuals) --------------
433
+ if (any(c(" all" , " qq" ) %in% check )) {
434
+ dat $ QQ <- switch (residual_type ,
435
+ simulated = .safe(simulate_residuals(model , ... )),
436
+ .diag_qq(model , model_info = model_info , verbose = verbose )
437
+ )
438
+ }
439
+
440
+ # Random Effects Q-Q plot (normality of BLUPs) --------------
441
+ if (any(c(" all" , " reqq" ) %in% check )) {
442
+ dat $ REQQ <- .diag_reqq(model , level = 0.95 , model_info = model_info , verbose = verbose )
443
+ }
444
+
445
+ # normal-curve plot (normality of residuals) --------------
446
+ if (any(c(" all" , " normality" ) %in% check )) {
447
+ dat $ NORM <- .diag_norm(model , verbose = verbose )
448
+ }
449
+
450
+ # non-constant variance (heteroskedasticity, liniearity) --------------
451
+ if (any(c(" all" , " ncv" , " linearity" ) %in% check )) {
452
+ dat $ NCV <- .diag_ncv(model , verbose = verbose )
453
+ }
454
+
455
+ # homogeneity of variance --------------
456
+ if (any(c(" all" , " homogeneity" ) %in% check )) {
457
+ dat $ HOMOGENEITY <- .diag_homogeneity(model , verbose = verbose )
458
+ }
459
+
460
+ # outliers --------------
461
+ if (any(c(" all" , " outliers" ) %in% check )) {
462
+ dat $ OUTLIERS <- .safe(check_outliers(model , method = " cook" ))
463
+ if (is.null(dat $ OUTLIERS )) {
464
+ threshold <- NULL
465
+ } else {
466
+ threshold <- attributes(dat $ OUTLIERS )$ threshold $ cook
467
+ }
468
+ dat $ INFLUENTIAL <- .influential_obs(model , threshold = threshold )
469
+ }
470
+
471
+ # posterior predictive checks --------------
472
+ if (any(c(" all" , " pp_check" ) %in% check )) {
473
+ dat $ PP_CHECK <- .safe(check_predictions(model , ... ))
432
474
}
433
- dat $ INFLUENTIAL <- .influential_obs(model , threshold = threshold )
434
- dat $ PP_CHECK <- .safe(check_predictions(model , ... ))
435
475
436
476
dat <- insight :: compact_list(dat )
437
477
class(dat ) <- c(" check_model" , " see_check_model" )
@@ -442,28 +482,55 @@ check_model.DHARMa <- check_model.performance_simres
442
482
443
483
# compile plots for checks of generalized linear models ------------------------
444
484
445
- .check_assumptions_glm <- function (model , model_info , residual_type = " simulated" , verbose = TRUE , ... ) {
485
+ .check_assumptions_glm <- function (model , model_info , check = " all " , residual_type = " simulated" , verbose = TRUE , ... ) {
446
486
dat <- list ()
447
487
448
- dat $ VIF <- .diag_vif(model , verbose = verbose )
449
- dat $ QQ <- switch (residual_type ,
450
- simulated = simulate_residuals(model , ... ),
451
- .diag_qq(model , model_info = model_info , verbose = verbose )
452
- )
453
- dat $ HOMOGENEITY <- .diag_homogeneity(model , verbose = verbose )
454
- dat $ REQQ <- .diag_reqq(model , level = 0.95 , model_info = model_info , verbose = verbose )
455
- dat $ OUTLIERS <- .safe(check_outliers(model , method = " cook" ))
456
- if (is.null(dat $ OUTLIERS )) {
457
- threshold <- NULL
458
- } else {
459
- threshold <- attributes(dat $ OUTLIERS )$ threshold $ cook
488
+ # multicollinearity --------------
489
+ if (any(c(" all" , " vif" ) %in% check )) {
490
+ dat $ VIF <- .diag_vif(model , verbose = verbose )
491
+ }
492
+
493
+ # Q-Q plot (normality/uniformity of residuals) --------------
494
+ if (any(c(" all" , " qq" ) %in% check )) {
495
+ dat $ QQ <- switch (residual_type ,
496
+ simulated = .safe(simulate_residuals(model , ... )),
497
+ .diag_qq(model , model_info = model_info , verbose = verbose )
498
+ )
499
+ }
500
+
501
+ # homogeneity of variance --------------
502
+ if (any(c(" all" , " homogeneity" ) %in% check )) {
503
+ dat $ HOMOGENEITY <- .diag_homogeneity(model , verbose = verbose )
504
+ }
505
+
506
+ # Random Effects Q-Q plot (normality of BLUPs) --------------
507
+ if (any(c(" all" , " reqq" ) %in% check )) {
508
+ dat $ REQQ <- .diag_reqq(model , level = 0.95 , model_info = model_info , verbose = verbose )
509
+ }
510
+
511
+ # outliers --------------
512
+ if (any(c(" all" , " outliers" ) %in% check )) {
513
+ dat $ OUTLIERS <- .safe(check_outliers(model , method = " cook" ))
514
+ if (is.null(dat $ OUTLIERS )) {
515
+ threshold <- NULL
516
+ } else {
517
+ threshold <- attributes(dat $ OUTLIERS )$ threshold $ cook
518
+ }
519
+ dat $ INFLUENTIAL <- .influential_obs(model , threshold = threshold )
460
520
}
461
- dat $ INFLUENTIAL <- .influential_obs(model , threshold = threshold )
462
- dat $ PP_CHECK <- .safe(check_predictions(model , ... ))
463
- if (isTRUE(model_info $ is_binomial )) {
521
+
522
+ # posterior predictive checks --------------
523
+ if (any(c(" all" , " pp_check" ) %in% check )) {
524
+ dat $ PP_CHECK <- .safe(check_predictions(model , ... ))
525
+ }
526
+
527
+ # binned residuals for bernoulli/binomial --------------
528
+ if (isTRUE(model_info $ is_binomial ) && any(c(" all" , " binned_residuals" ) %in% check )) {
464
529
dat $ BINNED_RESID <- .safe(binned_residuals(model , verbose = verbose , ... ))
465
530
}
466
- if (isTRUE(model_info $ is_count )) {
531
+
532
+ # misspecified dispersion and zero-inflation --------------
533
+ if (isTRUE(model_info $ is_count ) && any(c(" all" , " overdispersion" ) %in% check )) {
467
534
dat $ OVERDISPERSION <- .diag_overdispersion(model )
468
535
}
469
536
0 commit comments