├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ └── test-coverage.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── data_penguins.R ├── helper_checks.R ├── helper_glm_actual.R ├── helper_label.R ├── helper_plotly_label.R ├── helper_plotly_title.R ├── helper_resid.R ├── plot_auxboxplot.R ├── plot_auxhist.R ├── plot_auxindex.R ├── plot_auxqq.R ├── plot_auxresid.R ├── plot_boxplot.R ├── plot_constlev.R ├── plot_cookd.R ├── plot_hist.R ├── plot_index.R ├── plot_lev.R ├── plot_ls.R ├── plot_qq.R ├── plot_resid.R ├── plot_yvp.R ├── resid_auxpanel.R ├── resid_calibrate.R ├── resid_compare.R ├── resid_interact.R ├── resid_panel.R └── resid_xpanel.R ├── README.Rmd ├── README.md ├── cran-comments.md ├── data └── penguins.rda ├── docs ├── 404.html ├── LICENSE-text.html ├── apple-touch-icon-120x120.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon.png ├── articles │ ├── index.html │ ├── introduction.html │ └── introduction_files │ │ ├── crosstalk-1.1.1 │ │ ├── css │ │ │ └── crosstalk.css │ │ └── js │ │ │ ├── crosstalk.js │ │ │ ├── crosstalk.js.map │ │ │ ├── crosstalk.min.js │ │ │ └── crosstalk.min.js.map │ │ ├── figure-html │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-12-1.png │ │ ├── unnamed-chunk-14-1.png │ │ ├── unnamed-chunk-17-1.png │ │ ├── unnamed-chunk-4-1.png │ │ ├── unnamed-chunk-5-1.png │ │ ├── unnamed-chunk-8-1.png │ │ └── unnamed-chunk-9-1.png │ │ ├── htmlwidgets-1.5.3 │ │ └── htmlwidgets.js │ │ ├── jquery-3.5.1 │ │ ├── jquery-AUTHORS.txt │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map │ │ ├── plotly-binding-4.9.3 │ │ └── plotly.js │ │ ├── plotly-htmlwidgets-css-1.57.1 │ │ └── plotly-htmlwidgets.css │ │ ├── plotly-main-1.57.1 │ │ └── plotly-latest.min.js │ │ └── typedarray-0.1 │ │ └── typedarray.min.js ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── index.html ├── link.svg ├── logo.png ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── Rplot002.png │ ├── Rplot003.png │ ├── Rplot004.png │ ├── figures │ │ ├── README │ │ │ ├── unnamed-chunk-4-1.png │ │ │ ├── unnamed-chunk-4-2.png │ │ │ ├── unnamed-chunk-4-3.png │ │ │ ├── unnamed-chunk-6-1.png │ │ │ ├── unnamed-chunk-6-2.png │ │ │ ├── unnamed-chunk-7-1.png │ │ │ └── unnamed-chunk-8-1.png │ │ ├── interact.gif │ │ ├── logo.png │ │ ├── readme-unnamed-chunk-4-1.png │ │ ├── readme-unnamed-chunk-4-2.png │ │ ├── readme-unnamed-chunk-4-3.png │ │ ├── readme-unnamed-chunk-6-1.png │ │ ├── readme-unnamed-chunk-6-2.png │ │ ├── readme-unnamed-chunk-7-1.png │ │ ├── readme-unnamed-chunk-8-1.png │ │ └── static │ │ │ ├── interact.gif │ │ │ └── logo.png │ ├── index.html │ ├── libs │ │ ├── crosstalk-1.1.1 │ │ │ ├── css │ │ │ │ └── crosstalk.css │ │ │ └── js │ │ │ │ ├── crosstalk.js │ │ │ │ ├── crosstalk.js.map │ │ │ │ ├── crosstalk.min.js │ │ │ │ └── crosstalk.min.js.map │ │ ├── htmlwidgets-1.5.3 │ │ │ └── htmlwidgets.js │ │ ├── jquery-3.5.1 │ │ │ ├── jquery-AUTHORS.txt │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ └── jquery.min.map │ │ ├── plotly-binding-4.9.3 │ │ │ └── plotly.js │ │ ├── plotly-htmlwidgets-css-1.57.1 │ │ │ └── plotly-htmlwidgets.css │ │ ├── plotly-main-1.57.1 │ │ │ └── plotly-latest.min.js │ │ └── typedarray-0.1 │ │ │ └── typedarray.min.js │ ├── penguins.html │ ├── resid_auxpanel-1.png │ ├── resid_auxpanel.html │ ├── resid_compare-1.png │ ├── resid_compare-2.png │ ├── resid_compare.html │ ├── resid_interact.html │ ├── resid_panel-1.png │ ├── resid_panel-2.png │ ├── resid_panel-3.png │ ├── resid_panel-4.png │ ├── resid_panel.html │ ├── resid_xpanel-1.png │ ├── resid_xpanel-2.png │ └── resid_xpanel.html └── sitemap.xml ├── inst ├── cleaning_penguins_data.R ├── figures │ ├── interact.gif │ ├── logo.png │ ├── readme-unnamed-chunk-4-1.png │ ├── readme-unnamed-chunk-4-2.png │ ├── readme-unnamed-chunk-4-3.png │ ├── readme-unnamed-chunk-6-1.png │ ├── readme-unnamed-chunk-6-2.png │ ├── readme-unnamed-chunk-7-1.png │ └── readme-unnamed-chunk-8-1.png ├── ideas-for-future-work.md ├── penguins.txt ├── residuals.Rmd └── sticker_code.R ├── man ├── penguins.Rd ├── resid_auxpanel.Rd ├── resid_calibrate.Rd ├── resid_compare.Rd ├── resid_interact.Rd ├── resid_panel.Rd └── resid_xpanel.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── tests ├── testthat.R └── testthat │ ├── _snaps │ └── resid_panel │ │ ├── formatting-options-all-nrow-1.svg │ │ ├── formatting-options-all-nrow-3.svg │ │ ├── glm-binomial-plots-all.svg │ │ ├── glm-binomial-type-deviance.svg │ │ ├── glm-binomial-type-pearson.svg │ │ ├── glm-binomial-type-response.svg │ │ ├── glm-binomial-type-stand-deviance.svg │ │ ├── glm-binomial-type-stand-pearson.svg │ │ ├── glmer-binomial-plots-all.svg │ │ ├── glmer-binomial-type-deviance.svg │ │ ├── glmer-binomial-type-pearson.svg │ │ ├── glmer-binomial-type-response.svg │ │ ├── glmer-poisson-plots-all.svg │ │ ├── glmer-poisson-type-deviance.svg │ │ ├── glmer-poisson-type-pearson.svg │ │ ├── glmer-poisson-type-response.svg │ │ ├── lme-plots-all.svg │ │ ├── lme-type-pearson.svg │ │ ├── lme-type-response.svg │ │ ├── lmer-plots-all.svg │ │ ├── lmer-type-pearson.svg │ │ ├── lmer-type-response.svg │ │ ├── lmertest-plots-all.svg │ │ ├── panel-options-no-plots-specified.svg │ │ ├── panel-options-plots-all.svg │ │ ├── panel-options-plots-c-boxplot-cookd.svg │ │ ├── panel-options-plots-default-pearson.svg │ │ ├── panel-options-plots-r.svg │ │ └── panel-options-plots-sas.svg │ └── test-resid_panel.R └── vignettes └── introduction.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^codecov.yml$ 4 | ^cran-comments.md$ 5 | ^CRAN-RELEASE$ 6 | ^doc$ 7 | ^docs$ 8 | ^figures$ 9 | ^\.github$ 10 | ^Ideas for Future Work$ 11 | ^Meta$ 12 | ^pkgdown$ 13 | ^README_files$ 14 | ^README\.Rmd$ 15 | ^residuals.Rmd$ 16 | ^tests.R$ 17 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | 8 | name: R-CMD-check.yaml 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | R-CMD-check: 14 | runs-on: ${{ matrix.config.os }} 15 | 16 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 17 | 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | config: 22 | - {os: macos-latest, r: 'release'} 23 | - {os: windows-latest, r: 'release'} 24 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 25 | - {os: ubuntu-latest, r: 'release'} 26 | - {os: ubuntu-latest, r: 'oldrel-1'} 27 | 28 | env: 29 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 30 | R_KEEP_PKG_SOURCE: yes 31 | 32 | steps: 33 | - uses: actions/checkout@v4 34 | 35 | - uses: r-lib/actions/setup-pandoc@v2 36 | 37 | - uses: r-lib/actions/setup-r@v2 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | http-user-agent: ${{ matrix.config.http-user-agent }} 41 | use-public-rspm: true 42 | 43 | - uses: r-lib/actions/setup-r-dependencies@v2 44 | with: 45 | extra-packages: any::rcmdcheck 46 | needs: check 47 | 48 | - uses: r-lib/actions/check-r-package@v2 49 | with: 50 | upload-snapshots: true 51 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 52 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | 8 | name: test-coverage.yaml 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | test-coverage: 14 | runs-on: ubuntu-latest 15 | env: 16 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - uses: r-lib/actions/setup-r@v2 22 | with: 23 | use-public-rspm: true 24 | 25 | - uses: r-lib/actions/setup-r-dependencies@v2 26 | with: 27 | extra-packages: any::covr, any::xml2 28 | needs: coverage 29 | 30 | - name: Test coverage 31 | run: | 32 | cov <- covr::package_coverage( 33 | quiet = FALSE, 34 | clean = FALSE, 35 | install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") 36 | ) 37 | covr::to_cobertura(cov) 38 | shell: Rscript {0} 39 | 40 | - uses: codecov/codecov-action@v4 41 | with: 42 | # Fail if error if not on PR, or if on PR and token is given 43 | fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }} 44 | file: ./cobertura.xml 45 | plugin: noop 46 | disable_search: true 47 | token: ${{ secrets.CODECOV_TOKEN }} 48 | 49 | - name: Show testthat output 50 | if: always() 51 | run: | 52 | ## -------------------------------------------------------------------- 53 | find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true 54 | shell: bash 55 | 56 | - name: Upload test results 57 | if: failure() 58 | uses: actions/upload-artifact@v4 59 | with: 60 | name: coverage-test-failures 61 | path: ${{ runner.temp }}/package 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rproj 3 | .Rhistory 4 | .RData 5 | .Ruserdata 6 | *.Rproj 7 | *.DS_Store 8 | doc 9 | Meta 10 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ggResidpanel 2 | Type: Package 3 | Title: Panels and Interactive Versions of Diagnostic Plots using 'ggplot2' 4 | Version: 0.3.0.9000 5 | Authors@R: c( 6 | person( 7 | "Katherine", "Goode", 8 | email = "katherine.j.goode@gmail.com", 9 | role = c("aut", "cre") 10 | ), 11 | person( 12 | "Kathleen", "Rey", 13 | email = "kprey@iastate.edu", 14 | role = c("aut")), 15 | person( 16 | "Greenwood", "Mark", 17 | email = "greenwood@montana.edu", 18 | role = c("ctb")) 19 | ) 20 | Description: An R package for creating diagnostic plots for models. The package 21 | allows for the creation of panels of plots and interactive plots. 22 | License: MIT + file LICENSE 23 | Encoding: UTF-8 24 | LazyData: true 25 | URL: https://goodekat.github.io/ggResidpanel/ 26 | Imports: 27 | cowplot, 28 | ggplot2, 29 | grDevices, 30 | grid, 31 | MASS, 32 | methods, 33 | plotly, 34 | qqplotr, 35 | rlang, 36 | stats, 37 | stringr 38 | RoxygenNote: 7.3.2 39 | Suggests: 40 | dplyr, 41 | forcats, 42 | knitr, 43 | lme4, 44 | lmerTest, 45 | nlme, 46 | randomForest, 47 | rmarkdown, 48 | rpart, 49 | testthat (>= 3.0.0), 50 | vdiffr, 51 | wesanderson 52 | VignetteBuilder: knitr 53 | Depends: R (>= 3.0.0) 54 | Config/testthat/edition: 3 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2019 2 | COPYRIGHT HOLDER: Katherine J Goode 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(resid_auxpanel) 4 | export(resid_calibrate) 5 | export(resid_compare) 6 | export(resid_interact) 7 | export(resid_panel) 8 | export(resid_xpanel) 9 | importFrom(MASS,stdres) 10 | importFrom(cowplot,draw_label) 11 | importFrom(cowplot,ggdraw) 12 | importFrom(cowplot,plot_grid) 13 | importFrom(ggplot2,aes) 14 | importFrom(ggplot2,after_stat) 15 | importFrom(ggplot2,coord_fixed) 16 | importFrom(ggplot2,element_blank) 17 | importFrom(ggplot2,element_text) 18 | importFrom(ggplot2,expand_limits) 19 | importFrom(ggplot2,geom_abline) 20 | importFrom(ggplot2,geom_boxplot) 21 | importFrom(ggplot2,geom_histogram) 22 | importFrom(ggplot2,geom_hline) 23 | importFrom(ggplot2,geom_jitter) 24 | importFrom(ggplot2,geom_line) 25 | importFrom(ggplot2,geom_point) 26 | importFrom(ggplot2,geom_segment) 27 | importFrom(ggplot2,geom_smooth) 28 | importFrom(ggplot2,geom_text) 29 | importFrom(ggplot2,geom_violin) 30 | importFrom(ggplot2,geom_vline) 31 | importFrom(ggplot2,ggplot) 32 | importFrom(ggplot2,ggplotGrob) 33 | importFrom(ggplot2,ggplot_build) 34 | importFrom(ggplot2,labs) 35 | importFrom(ggplot2,scale_color_gradient2) 36 | importFrom(ggplot2,scale_x_continuous) 37 | importFrom(ggplot2,scale_y_continuous) 38 | importFrom(ggplot2,stat_function) 39 | importFrom(ggplot2,theme) 40 | importFrom(ggplot2,theme_bw) 41 | importFrom(ggplot2,theme_classic) 42 | importFrom(ggplot2,theme_grey) 43 | importFrom(ggplot2,xlab) 44 | importFrom(ggplot2,xlim) 45 | importFrom(ggplot2,ylab) 46 | importFrom(grDevices,extendrange) 47 | importFrom(grid,gpar) 48 | importFrom(grid,textGrob) 49 | importFrom(methods,is) 50 | importFrom(plotly,"%>%") 51 | importFrom(plotly,ggplotly) 52 | importFrom(plotly,layout) 53 | importFrom(plotly,style) 54 | importFrom(plotly,subplot) 55 | importFrom(qqplotr,stat_qq_band) 56 | importFrom(qqplotr,stat_qq_line) 57 | importFrom(qqplotr,stat_qq_point) 58 | importFrom(rlang,.data) 59 | importFrom(stats,cooks.distance) 60 | importFrom(stats,dnorm) 61 | importFrom(stats,fitted) 62 | importFrom(stats,formula) 63 | importFrom(stats,hatvalues) 64 | importFrom(stats,lm) 65 | importFrom(stats,lowess) 66 | importFrom(stats,model.frame) 67 | importFrom(stats,resid) 68 | importFrom(stats,sd) 69 | importFrom(stats,simulate) 70 | importFrom(stringr,str_sub) 71 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # ggResidpanel 0.4.0 2 | 3 | ## Major 4 | 5 | - Added resid_calibrate 6 | - For lm model: 7 | - Standardized residuals are now the default instead of raw residuals 8 | - Fixed issue when leverage is equal to 1 when computing standardized residuals - report Pearson residuals instead 9 | - Added alpha value in all functions 10 | - Adjustments to Cook's D plots 11 | - "Return a warning if any of the leverage values are equal to 1 and add lines to plot" 12 | - Need to add more descriptions here 13 | - In plot_constlev, removed "Compute the values for the lowess curve" 14 | - In plot_lev, : 15 | - "Create the cutoff SAS uses with Cook's D" 16 | - "Count number over cutoff" 17 | - Adjusted the way constant leverage is handled 18 | - Added Cook's D values 19 | - When creating hat values, "Add more resolution for large n" 20 | - In plot_ls, "If smoother is set to true, do not add it to the plot" 21 | - Adjustments to the smoother options across various plot types 22 | 23 | ## Minor 24 | 25 | - Typo fixes in documentation 26 | - Small fixes to code for better practices 27 | - Small updates to plot_hist grid 28 | - Clean up of some plot labels 29 | 30 | # ggResidpanel 0.3.0 31 | 32 | ## Major: 33 | 34 | - changed resid_interact to allow for a panel of interactive plots 35 | - added the functions of resid_xpanel and resid_compare 36 | - added model types of lmerTest and lme 37 | - added an introductory vignette 38 | 39 | ## Minor: 40 | 41 | - updated documentation 42 | - added Cook's distance values to residual-leverage plot 43 | - reordered plots in "all" panels 44 | - included penguins data 45 | - rounded number in tool tip in resid_interact 46 | - fixed some bugs in the code 47 | 48 | # ggResidpanel 0.2.0 and earlier 49 | 50 | - first versions of ggResidpanel (the progression was not documented) 51 | - introduced the functions of resid_panel, resid_interact, and resid_auxpanel 52 | - allowed options in the functions for formatting options 53 | -------------------------------------------------------------------------------- /R/data_penguins.R: -------------------------------------------------------------------------------- 1 | #' Penguins Dataset 2 | #' 3 | #' A dataset that contains information from a study done on dives of emperor penguins by 4 | #' Jessica Meir and others. The scientists were interested in understanding how the heart 5 | #' rate of the penguins relates to the depth and duration of the dive. The study involved 6 | #' attaching a device to penguins that recorded the heart rate of the bird during a dive. 7 | #' The dataset contains multiple observations recorded from 9 penguins. The dataset has 8 | #' 125 observations and 4 variables. 9 | #' 10 | #' 11 | #' @details The variables in the dataset are as follows. 12 | #' \tabular{ll}{ 13 | #' \code{heartrate} \tab Heart rate of the penguin during the dive (beats per minute) \cr 14 | #' \code{depth} \tab Depth of the dive (meters) \cr 15 | #' \code{duration} \tab Duration of the dive (minutes) \cr 16 | #' \code{bird} \tab The id number associated with a penguin} 17 | #' 18 | #' @format A data.frame. 19 | #' 20 | #' @source \url{https://dasl.datadescription.com/datafile/penguins/?_sfm_methods=Regression&_sfm_cases=4+59943&sf_paged=9} 21 | 22 | "penguins" 23 | -------------------------------------------------------------------------------- /R/helper_checks.R: -------------------------------------------------------------------------------- 1 | # Check functions to use in plot functions that return errors or warnings to users. 2 | 3 | ## CHECKS THAT RETURN ERRORS --------------------------------------------------------------- 4 | 5 | # Return an error if an acceptable model type is not entered in the function 6 | check_modeltype <- function(model){ 7 | 8 | if(!(class(model)[1] %in% c("lm", "glm", "lme", "lmerMod", "lmerModLmerTest", "glmerMod"))) 9 | stop("This function requires a model to be input. Accepted models 10 | currently are lm, glm, lme, lmer, lmerTest, and glmer.") 11 | 12 | } 13 | 14 | # Return an error if the requested residual type is not available for the model type 15 | check_residualtype <- function(model, type){ 16 | 17 | type <- tolower(type) 18 | 19 | if(!is.na(type)){ 20 | if(class(model)[1] == "lm"){ 21 | if(!(type %in% c("response", "pearson", "standardized"))){ 22 | stop("The requested residual type is not available for an 'lm' model. Please select 23 | from the following options for an 'lm' model: response, pearson, or standardized.") 24 | } 25 | } else if(class(model)[1] == "glm"){ 26 | if(!(type %in% c("response", "pearson", "deviance", "stand.pearson", "stand.deviance"))){ 27 | stop("The requested residual type is not available for a 'glm' model. Please select 28 | from the following options for a 'glm' model: response, pearson, deviance, 29 | stand.deviance, or stand.pearson.") 30 | } 31 | } else if(class(model)[1] == "lmerMod"){ 32 | if(!(type %in% c("response", "pearson"))){ 33 | stop("The requested residual type is not available for an 'lmer' model. Please 34 | select from the following options for an 'lmer' model: response or pearson.") 35 | } 36 | } else if(class(model)[1] == "lmerModLmerTest"){ 37 | if(!(type %in% c("response", "pearson"))){ 38 | stop("The requested residual type is not available for an 'lmerTest' model. Please 39 | select from the following options for an 'lmerTest' model: response or pearson.") 40 | } 41 | } else if(class(model)[1] == "lme"){ 42 | if(!(type %in% c("response", "pearson"))){ 43 | stop("The requested residual type is not available for an 'lme' model. Please 44 | select from the following options for an 'lme' model: response or pearson.") 45 | } 46 | } else if(class(model)[1] == "glmerMod"){ 47 | if(!(type %in% c("response", "pearson", "deviance"))){ 48 | stop("The requested residual type is not available for a 'glmer' model. Please 49 | select from the following options for a 'glmer' model: response, pearson, 50 | or deviance.") 51 | } 52 | } 53 | } 54 | 55 | } 56 | 57 | # Return an error if the requested plots involve standardizing residuals for an 'lmer' or 58 | # a 'glmer' model 59 | check_standardized <- function(model, plots){ 60 | 61 | if(class(model)[1] %in% c("lme", "lmerMod", "lmerModLmerTest", "glmerMod")){ 62 | if("ls" %in% plots |"lev" %in% plots | "R" %in% plots){ 63 | stop("The requested plot or panel uses standardized residuals, which are not 64 | currently available for 'lme', 'lmer', 'lmerTest', or 'glmer' models.") 65 | } 66 | } 67 | 68 | } 69 | 70 | # Return an error if Cook's D plot is requested for an 'lmer' or 'glmer' model 71 | check_cooksd <- function(model, plots){ 72 | if(class(model)[1] %in% c("lme", "lmerMod", "lmerModLmerTest", "glmerMod")){ 73 | if("cookd" %in% plots){ 74 | stop("The Cook's D plot is unavailable for 'lme', 'lmer', 'lmerTest', and 'glmer' models.") 75 | } 76 | } 77 | } 78 | 79 | 80 | ## CHECKS THAT RETURN WARNINGS ------------------------------------------------------------- 81 | 82 | # Return a warning if the smoother option is not specified correctly and return 83 | # the default option if not specified 84 | check_smoother <- function(smoother){ 85 | if(smoother == TRUE | smoother == FALSE){ 86 | } else{ 87 | smoother <- FALSE 88 | warning("The smoother option for residual plot not was specified correctly. 89 | The default option will be used. Accepted options are TRUE or FALSE.") 90 | } 91 | return(smoother) 92 | } 93 | 94 | # Return a warning if the theme is not specified correctly and return the default 95 | # option if not specified 96 | check_theme <- function(theme){ 97 | if(theme == "bw" | theme == "classic" | theme == "grey" | theme == "gray"){ 98 | } else{ 99 | theme <- "bw" 100 | warning("The theme option was not specified correctly. The default theme 101 | will be used. Accepted themes are 'bw', 'classic', and 'grey' (or 'gray').") 102 | } 103 | return(theme) 104 | } 105 | 106 | # Return a warning if the title option is not specified correctly and return the 107 | # default option if not specified 108 | check_title <- function(title.opt){ 109 | 110 | if(title.opt == TRUE | title.opt == FALSE){ 111 | } else{ 112 | title.opt <- TRUE 113 | warning("The title option was not specified correctly. The default title 114 | option will be used. Accepted options are TRUE or FALSE.") 115 | } 116 | 117 | return(title.opt) 118 | 119 | } 120 | 121 | # Return warning if consant leverage or any observations have a leverage value of 1 122 | check_leverage <- function(model, plots){ 123 | 124 | if(class(model)[1] %in% c("lm", "glm")){ 125 | 126 | if("all" %in% plots | "R" %in% plots | "lev" %in% plots){ 127 | 128 | leverage_val <- hatvalues(model) 129 | 130 | zero_range <- function(x, tol = .Machine$double.eps ^ 0.5) { 131 | if (length(x) == 1) return(TRUE) 132 | x <- range(x) / mean(x) 133 | isTRUE(all.equal(x[1], x[2], tolerance = tol)) 134 | } 135 | 136 | if(zero_range(leverage_val) == TRUE){ 137 | warning("Note that this model has constant leverage.") 138 | } 139 | 140 | } 141 | 142 | } 143 | 144 | } 145 | -------------------------------------------------------------------------------- /R/helper_glm_actual.R: -------------------------------------------------------------------------------- 1 | # Actual values from a glm model. 2 | 3 | # Finds the number of successes divided by the total 4 | 5 | helper_glm_actual <- function(model){ 6 | ############################################################### 7 | #Calculates the proportion of successes for the yvp plot 8 | 9 | #The methods for acquiring the data are different for mixed models so separated 10 | #based on model type 11 | if(class(model)[1]=="glm"){ 12 | 13 | #This code stackes the sucesses and failures into one vector 14 | stacked_successs_total <- data.frame(do.call('rbind', strsplit(as.character(model$model[[1]]),' ',fixed=TRUE))) 15 | #Split into successes and failures 16 | successes <- as.numeric(as.character(stacked_successs_total[1:(nrow(stacked_successs_total)/2),])) 17 | failures <- as.numeric(as.character(stacked_successs_total[((nrow(stacked_successs_total)/2)+1):nrow(stacked_successs_total),])) 18 | total <- successes+failures 19 | 20 | return(successes/total) 21 | }else if (class(model)[1]=="glmerMod") { 22 | 23 | stacked_successs_total <- data.frame(do.call('rbind', strsplit(as.character(model@frame[[1]]),' ',fixed=TRUE))) 24 | successes <- as.numeric(as.character(stacked_successs_total[1:(nrow(stacked_successs_total)/2),])) 25 | failures <- as.numeric(as.character(stacked_successs_total[((nrow(stacked_successs_total)/2)+1):nrow(stacked_successs_total),])) 26 | total <- successes+failures 27 | 28 | return(successes/total) 29 | } 30 | ################################################################# 31 | 32 | } 33 | 34 | # helper_glm_actual <- function(model){ 35 | # ############################################################### 36 | # #Create Data to use as labels 37 | # #The only way to get plotly to plot the y, the x's, and the observation when 38 | # #it is not included in aes() is to create a vector where each value of that 39 | # #Vector contains all of the above information. The plotly option 'tooltips' can 40 | # #then be used to select which variables to print in plotly which would be the 41 | # #single variable 'Data' containing all the above information 42 | # 43 | # #The methods for acquiring the data are different for mixed models so separated 44 | # #based on model type 45 | # if(class(model)[1]%in%c("lm", "glm")){ 46 | # #Get names of variables 47 | # names_data <- names(model$model) 48 | # #Get data used in model from model 49 | # plotly_data <- data.frame(as.matrix(model$model)) 50 | # 51 | # #If binomial, the response variables are two columns 52 | # if(class(model)[1]=="glm"){ 53 | # if(model$family[[1]]=="binomial"){ 54 | # 55 | # #The next set of code extracts the column names from the 56 | # #cbind statement used to create the number of successes and 57 | # #number of failures 58 | # 59 | # #Find first parentheses 60 | # firstp <- as.numeric(gregexpr(pattern ='\\(',names_data[1])[1]) 61 | # #Find end parentheses 62 | # lastp <- as.numeric(gregexpr(pattern ='\\)',names_data[1])[1]) 63 | # #Find first comma 64 | # firstc <- as.numeric(gregexpr(pattern ='\\,',names_data[1])[1]) 65 | # #Grab the name of the number of successes which is between the 66 | # #first parentheses and the comma 67 | # names(plotly_data)[1] <- str_sub(names_data[1], {firstp+1}, {firstc-1}) 68 | # 69 | # #Check if the person gave the number of failures or calculated the number 70 | # #of failures 71 | # if (grepl("\\-", names_data[1])){ 72 | # #Find the '-' sign: the name of the number of trials will preceed it 73 | # firstm <- as.numeric(gregexpr(pattern ='\\-',names_data[1])[1]) 74 | # #Set the name of the trials by extracting everything from the comma 75 | # #to the minus sign and remove extra blanks 76 | # names(plotly_data)[2] <- gsub(" ", "",str_sub(names_data[1], {firstc+1}, {firstm-1})) 77 | # 78 | # #Make sure are numeric (I no longer need these so commented out) 79 | # plotly_data[,1] <- as.numeric(as.character(plotly_data[,1])) 80 | # plotly_data[,2] <- as.numeric(as.character(plotly_data[,2])) 81 | # 82 | # #Second column needs to contain total so add first two 83 | # plotly_data[,2] <- plotly_data[,1]+plotly_data[,2] 84 | # }else{ 85 | # #if the second column does not contain a minus, the user ented the number 86 | # #of failures so don't add the first two together and grab the name 87 | # #of the failures between the comma and the end parentheses and removed extra 88 | # #blanks 89 | # names(plotly_data)[2] <- gsub(" ", "",str_sub(names_data[1], {firstc+1}, {lastp-1})) 90 | # } 91 | # } 92 | # } 93 | # 94 | # return(plotly_data[1]/plotly_data[2]) 95 | # }else if (class(model)[1]%in%c("lmerMod", "lmerModLmerTest", "glmerMod")) { 96 | # names_data <- names(model@frame) 97 | # plotly_data <- data.frame(as.matrix(model@frame)) 98 | # 99 | # #If binomial, the response variables are two columsn 100 | # if(class(model)[1]=="glmerMod"){ 101 | # if(model@resp$family[[1]]=="binomial"){ 102 | # 103 | # #Find first parentheses 104 | # firstp <- as.numeric(gregexpr(pattern ='\\(',names_data[1])[1]) 105 | # #Find end parentheses 106 | # lastp <- as.numeric(gregexpr(pattern ='\\)',names_data[1])[1]) 107 | # #Find first comma 108 | # firstc <- as.numeric(gregexpr(pattern ='\\,',names_data[1])[1]) 109 | # #Grab the name of the number of successes 110 | # names(plotly_data)[1] <- str_sub(names_data[1], {firstp+1}, {firstc-1}) 111 | # 112 | # #Check if the person gave the number of failures or calculated the number 113 | # #of failures 114 | # if (grepl("\\-", names_data[1])){ 115 | # #First the '-' sign 116 | # firstm <- as.numeric(gregexpr(pattern ='\\-',names_data[1])[1]) 117 | # #Set the name of the total 118 | # names(plotly_data)[2] <- gsub(" ", "",str_sub(names_data[1], {firstc+1}, {firstm-1})) 119 | # 120 | # #Make sure are numeric (don't need these lines anymore) 121 | # plotly_data[,1] <- as.numeric(as.character(plotly_data[,1])) 122 | # plotly_data[,2] <- as.numeric(as.character(plotly_data[,2])) 123 | # 124 | # #Second column needs to contain total so add first two 125 | # plotly_data[,2] <- plotly_data[,1]+plotly_data[,2] 126 | # }else{ 127 | # names(plotly_data)[2] <- gsub(" ", "",str_sub(names_data[1], {firstc+1}, {lastp-1})) 128 | # } 129 | # } 130 | # } 131 | # 132 | # return(as.numeric(plotly_data[,1]/plotly_data[,2])) 133 | # } 134 | # ################################################################# 135 | # 136 | # } 137 | -------------------------------------------------------------------------------- /R/helper_label.R: -------------------------------------------------------------------------------- 1 | # Labels for Plots. 2 | 3 | # Creates a label for the plots based on the type of residuals used 4 | helper_label <- function(type = NA, model){ 5 | if(!is.na(type)){ 6 | if (type == "response"){ 7 | return("Residuals") 8 | } else if (type =="pearson"){ 9 | return("Pearson Residuals") 10 | } else if (type == "deviance"){ 11 | return("Deviance Residuals") 12 | } else if (type == "standardized"){ 13 | return("Standardized Residuals") 14 | } else if (type == "stand.deviance"){ 15 | return("Standardized Deviance Residuals") 16 | } else if (type == "stand.pearson"){ 17 | return("Standardized Pearson Residuals") 18 | } 19 | } else { 20 | if(class(model)[1] == "lm"){ 21 | return("Residuals") 22 | } else if (class(model)[1] == "lmerMod"){ 23 | return("Pearson Residuals") 24 | } else if (class(model)[1] == "lme"){ 25 | return("Pearson Residuals") 26 | } else if (class(model)[1] == "lmerModLmerTest"){ 27 | return("Pearson Residuals") 28 | } else if (class(model)[1] == "glm"){ 29 | return("Deviance Residuals") 30 | } else if (class(model)[1] == "glmerMod"){ 31 | return("Deviance Residuals") 32 | } else{ 33 | return("Residuals") 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /R/helper_plotly_title.R: -------------------------------------------------------------------------------- 1 | # Function for positioning the titles with the ggplotly graphs 2 | 3 | helper_plotly_title <- function(plot){ 4 | 5 | title_info <- list( 6 | text = plot$labels$title, 7 | xref = "paper", 8 | yref = "paper", 9 | yanchor = "bottom", 10 | xanchor = "center", 11 | align = "center", 12 | x = 0.5, 13 | y = 1, 14 | showarrow = FALSE 15 | ) 16 | 17 | return(title_info) 18 | 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /R/helper_resid.R: -------------------------------------------------------------------------------- 1 | # Extended Residual Calculations. 2 | 3 | # Calculates residuals beyond what 'resid' can do 4 | helper_resid <- function(type = NA, model){ 5 | 6 | # lm residuals 7 | if(class(model)[1] == "lm"){ 8 | 9 | # Default: standardized residuals 10 | if(is.na(type) | type == "standardized"){ 11 | if (any(!is.finite(stdres(model)))){ 12 | warning("Leverage 1 observation(s) encountered, reporting Pearson Residuals") 13 | return(resid(model, type = "response") / summary(model)$sigma) 14 | } else { 15 | return(stdres(model)) 16 | } 17 | }else if(type == "pearson"){ 18 | return(resid(model, type = "response") / summary(model)$sigma) 19 | }else if(type == "response"){ 20 | return(resid(model, "response")) 21 | } 22 | 23 | 24 | # glm residuals 25 | } else if (class(model)[1] == "glm"){ 26 | 27 | # Default: deviance residuals 28 | if(is.na(type) | type == "deviance"){ 29 | return(resid(model, type = "deviance")) 30 | }else if (type == "response"){ 31 | return(resid(model, type = "response")) 32 | }else if (type == "pearson"){ 33 | return(resid(model, type = "pearson")) 34 | }else if (type == "stand.deviance"){ 35 | return((resid(model, type = "deviance")) / (sqrt(summary(model)$dispersion*(1 - hatvalues(model))))) 36 | }else if (type == "stand.pearson"){ 37 | return((resid(model, type = "pearson")) / (sqrt(summary(model)$dispersion*(1 - hatvalues(model))))) 38 | } 39 | 40 | # lme residuals 41 | } else if (class(model)[1] == "lme"){ 42 | 43 | # Default: Pearson residuals (condtional on BLUPs) 44 | if(is.na(type) | type == "pearson"){ 45 | return(resid(model, type = "response") / summary(model)$sigma) 46 | } else if (type == "response"){ 47 | return(resid(model, type = "response")) 48 | } 49 | 50 | # lmer residuals 51 | } else if (class(model)[1] == "lmerMod"){ 52 | 53 | # Default: Pearson residuals (condtional on BLUPs) 54 | if(is.na(type) | type == "pearson"){ 55 | return(resid(model, type = "response") / summary(model)$sigma) 56 | }else if (type == "response"){ 57 | return(resid(model, type = "response")) 58 | } 59 | 60 | # lmerTest residuals 61 | } else if (class(model)[1] == "lmerModLmerTest"){ 62 | 63 | # Default: Pearson residuals (condtional on BLUPs) 64 | if(is.na(type) | type == "pearson"){ 65 | return(resid(model, type = "response") / summary(model)$sigma) 66 | }else if (type == "response"){ 67 | return(resid(model, type = "response")) 68 | } 69 | 70 | # glmer residuals 71 | } else if (class(model)[1] == "glmerMod"){ 72 | 73 | # Default: deviance residuals 74 | if(is.na(type) | type == "deviance"){ 75 | return(resid(model, type = "deviance")) 76 | }else if (type == "response"){ 77 | return(resid(model, type = "response")) 78 | }else if (type == "pearson"){ 79 | return(resid(model, type = "pearson")) 80 | } 81 | } 82 | 83 | } 84 | 85 | -------------------------------------------------------------------------------- /R/plot_auxboxplot.R: -------------------------------------------------------------------------------- 1 | # Boxplot of Residuals. 2 | 3 | # Creates a boxplot from input residuals and predicted values 4 | plot_auxboxplot <- function( 5 | resid, 6 | theme, 7 | axis.text.size, 8 | title.text.size, 9 | title.opt 10 | ){ 11 | 12 | ## Creation of Values to Plot ----------------------------------------------------- 13 | 14 | # Create a data frame with the residuals 15 | model_values <- data.frame(Residual = resid) 16 | 17 | # Add an observation variable 18 | model_values$Observation <- 1:nrow(model_values) 19 | 20 | ## Creation of Plot --------------------------------------------------------------- 21 | 22 | # Create the boxplot of residuals 23 | plot <- 24 | ggplot( 25 | data = model_values, 26 | mapping = aes( 27 | x = " ", 28 | y = .data$Residual 29 | ) 30 | ) + 31 | geom_boxplot(width = .5) + 32 | geom_point(alpha = 0) + 33 | labs( 34 | x = " ", 35 | y = "Residuals" 36 | ) 37 | 38 | # Add theme to plot 39 | if (theme == "bw") { 40 | plot <- plot + theme_bw() 41 | } else if (theme == "classic") { 42 | plot <- plot + theme_classic() 43 | } else if (theme == "gray" | theme == "grey") { 44 | plot <- plot + theme_grey() 45 | } 46 | 47 | # Set text size of title and axis labels, 48 | # determine whether to include a title, 49 | # and return plot 50 | if (title.opt == TRUE) { 51 | plot + 52 | labs(title = "Boxplot") + 53 | theme( 54 | plot.title = element_text(size = title.text.size, face = "bold"), 55 | axis.title = element_text(size = axis.text.size) 56 | ) 57 | } else if (title.opt == FALSE) { 58 | plot + 59 | theme(axis.title = element_text(size = axis.text.size)) 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /R/plot_auxhist.R: -------------------------------------------------------------------------------- 1 | # Histogram of Residuals. 2 | 3 | # Creates a histogram of the input residuals 4 | plot_auxhist <- function( 5 | resid, 6 | bins, 7 | theme, 8 | axis.text.size, 9 | title.text.size, 10 | title.opt 11 | ) { 12 | 13 | ## Creation of Values to Plot ----------------------------------------------------- 14 | 15 | # If bins = NA, use default 16 | if (is.na(bins)) { 17 | bins <- 30 18 | } 19 | 20 | # Create a data frame withthe residuals 21 | model_values <- data.frame(Residual = resid) 22 | 23 | # Steps to make sure any huge outliers are not cut off 24 | if (min(model_values$Residual) < -4 * sd(model_values$Residual)) { 25 | min_x <- NA 26 | } else{ 27 | min_x <- -4 * sd(model_values$Residual) 28 | } 29 | if (max(model_values$Residual) > 4 * sd(model_values$Residual)) { 30 | max_x <- NA 31 | } else{ 32 | max_x <- 4 * sd(model_values$Residual) 33 | } 34 | 35 | ## Creation of Plot --------------------------------------------------------------- 36 | 37 | # Create the histogram of residuals 38 | if (is.na(min_x) & is.na(max_x)) { 39 | # Data is outside of 4*sd, so xlim is not used 40 | plot <- 41 | ggplot( 42 | data = model_values, 43 | mapping = aes(x = .data$Residual) 44 | ) + 45 | geom_histogram( 46 | mapping = aes( 47 | y = after_stat(.data$density), 48 | fill = after_stat(.data$count) 49 | ), 50 | color = "black", 51 | fill = "grey82", 52 | bins = bins 53 | ) + 54 | stat_function( 55 | fun = dnorm, 56 | color = "blue", 57 | args = list( 58 | mean = 0, 59 | sd = sd(model_values$Residual) 60 | ) 61 | ) + 62 | labs( 63 | x = "Residuals", 64 | y = "Density" 65 | ) 66 | 67 | } else{ 68 | # Data is not outside of 4*sd, so xlim is used 69 | plot <- 70 | ggplot( 71 | data = model_values, 72 | mapping = aes(x = .data$Residual) 73 | ) + 74 | geom_histogram( 75 | mapping = aes( 76 | y = after_stat(.data$density), 77 | fill = after_stat(.data$count) 78 | ), 79 | color = "black", 80 | fill = "grey82", 81 | bins = bins 82 | ) + 83 | stat_function( 84 | fun = dnorm, 85 | color = "blue", 86 | args = list( 87 | mean = 0, 88 | sd = sd(model_values$Residual) 89 | ) 90 | ) + 91 | labs( 92 | x = "Residuals", 93 | y = "Density" 94 | ) + 95 | xlim(c(min_x, max_x)) 96 | 97 | } 98 | 99 | # Add theme to plot 100 | if (theme == "bw") { 101 | plot <- plot + theme_bw() 102 | } else if (theme == "classic") { 103 | plot <- plot + theme_classic() 104 | } else if (theme == "gray" | theme == "grey") { 105 | plot <- plot + theme_grey() 106 | } 107 | 108 | # Set text size of title and axis labels, determine whether to include a title, 109 | # and return plot 110 | if (title.opt == TRUE) { 111 | plot + 112 | labs(title = "Histogram") + 113 | theme( 114 | plot.title = element_text(size = title.text.size, face = "bold"), 115 | axis.title = element_text(size = axis.text.size) 116 | ) 117 | } else if (title.opt == FALSE) { 118 | plot + theme(axis.title = element_text(size = axis.text.size)) 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /R/plot_auxindex.R: -------------------------------------------------------------------------------- 1 | # Residual vs Index Plot. 2 | 3 | # Creates a residual plot with the input residuals and predicted values 4 | plot_auxindex <- function( 5 | resid, 6 | smoother, 7 | theme, 8 | axis.text.size, 9 | title.text.size, 10 | title.opt, 11 | alpha 12 | ) { 13 | 14 | ## Creation of Values to Plot ----------------------------------------------------- 15 | 16 | # Create a data frame with the residuals 17 | model_values <- data.frame(Residual = resid) 18 | 19 | # Create a variable for observation number 20 | model_values$Observation <- 1:length(model_values$Residual) 21 | 22 | ## Creation of Plot --------------------------------------------------------------- 23 | 24 | # Create the residual plot 25 | plot <- 26 | ggplot( 27 | data = model_values, 28 | mapping = aes( 29 | x = .data$Observation, 30 | y = .data$Residual 31 | ) 32 | ) + 33 | geom_point(alpha = alpha) + 34 | geom_abline( 35 | slope = 0, 36 | intercept = 0, 37 | color = "blue" 38 | ) + 39 | labs( 40 | x = "Observation Number", 41 | y = "Residuals" 42 | ) 43 | 44 | # If smoother is set to true, add it to the plot 45 | if (smoother == TRUE) { 46 | plot <- plot + 47 | geom_smooth( 48 | method = "loess", 49 | se = FALSE, 50 | color = "red", 51 | linewidth = 0.5, 52 | formula = 'y ~ x' 53 | ) 54 | } 55 | 56 | # Add theme to plot 57 | if (theme == "bw") { 58 | plot <- plot + theme_bw() 59 | } else if (theme == "classic") { 60 | plot <- plot + theme_classic() 61 | } else if (theme == "gray" | theme == "grey") { 62 | plot <- plot + theme_grey() 63 | } 64 | 65 | # Set text size of title and axis labels, determine whether to include a title, 66 | # and return plot 67 | if (title.opt == TRUE) { 68 | plot + 69 | labs(title = "Index Plot") + 70 | theme( 71 | plot.title = element_text(size = title.text.size, face = "bold"), 72 | axis.title = element_text(size = axis.text.size) 73 | ) 74 | } else if (title.opt == FALSE) { 75 | plot + theme(axis.title = element_text(size = axis.text.size)) 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /R/plot_auxqq.R: -------------------------------------------------------------------------------- 1 | # Q-Q Plot. 2 | 3 | # Creates a Q-Q plot from the input residuals 4 | plot_auxqq <- function( 5 | resid, 6 | theme, 7 | axis.text.size, 8 | title.text.size, 9 | title.opt, 10 | qqline, 11 | qqbands, 12 | alpha 13 | ) { 14 | 15 | ## Creation of Values to Plot ----------------------------------------------------- 16 | 17 | # Create a data frame with the residuals 18 | model_values <- data.frame(Residual = resid) 19 | 20 | ## Creation of Plot --------------------------------------------------------------- 21 | 22 | # Create the qq plot 23 | if (qqbands == TRUE) { 24 | # Add bands if requested 25 | plot <- 26 | ggplot( 27 | data = model_values, 28 | mapping = aes(sample = .data$Residual) 29 | ) + 30 | stat_qq_band() + 31 | stat_qq_point(alpha = alpha) + 32 | labs( 33 | x = "Theoretical Quantiles", 34 | y = "Sample Quantiles" 35 | ) 36 | } else { 37 | # Don't add bands 38 | plot <- 39 | ggplot( 40 | data = model_values, 41 | mapping = aes(sample = .data$Residual) 42 | ) + 43 | stat_qq_point(alpha = alpha) + 44 | labs( 45 | x = "Theoretical Quantiles", 46 | y = "Sample Quantiles" 47 | ) 48 | } 49 | 50 | # Add a line if requested 51 | if (qqline == TRUE) { 52 | plot <- plot + stat_qq_line(color = "blue", linewidth = .5) 53 | } 54 | 55 | # Add theme to plot 56 | if (theme == "bw") { 57 | plot <- plot + theme_bw() 58 | } else if (theme == "classic") { 59 | plot <- plot + theme_classic() 60 | } else if (theme == "gray" | theme == "grey") { 61 | plot <- plot + theme_grey() 62 | } 63 | 64 | # Set text size of title and axis labels, determine whether to include a title, 65 | # and return plot 66 | if (title.opt == TRUE) { 67 | plot + 68 | labs(title = "Q-Q Plot") + 69 | theme( 70 | plot.title = element_text(size = title.text.size, face = "bold"), 71 | axis.title = element_text(size = axis.text.size) 72 | ) 73 | } else if (title.opt == FALSE) { 74 | plot + theme(axis.title = element_text(size = axis.text.size)) 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /R/plot_auxresid.R: -------------------------------------------------------------------------------- 1 | # Residual Plot. 2 | 3 | # Creates a residual plot with the input residuals and predicted values 4 | plot_auxresid <- function( 5 | resid, 6 | pred, 7 | smoother, 8 | theme, 9 | axis.text.size, 10 | title.text.size, 11 | title.opt, 12 | alpha 13 | ) { 14 | 15 | ## Creation of Values to Plot ----------------------------------------------------- 16 | 17 | # Create a data frame with the residuals 18 | model_values <- data.frame(Residual = resid, Prediction = pred) 19 | 20 | # Compute the values for the lowess curve 21 | model_values$Lowess.x <- 22 | lowess( 23 | x = model_values$Prediction, 24 | y = model_values$Residual 25 | )$x 26 | model_values$Lowess.y <- 27 | lowess( 28 | x = model_values$Prediction, 29 | y = model_values$Residual 30 | )$y 31 | 32 | ## Creation of Plot --------------------------------------------------------------- 33 | 34 | # Create the residual plot 35 | plot <- 36 | ggplot( 37 | data = model_values, 38 | mapping = aes( 39 | x = .data$Prediction, 40 | y = .data$Residual 41 | ) 42 | ) + 43 | geom_point(alpha = alpha) + 44 | geom_abline( 45 | slope = 0, 46 | intercept = 0, 47 | color = "blue" 48 | ) + 49 | labs( 50 | x = "Predicted Values", 51 | y = "Residuals" 52 | ) 53 | 54 | # If smoother is set to true, add it to the plot 55 | if (smoother == TRUE) { 56 | plot <- 57 | plot + 58 | geom_line( 59 | aes( 60 | x = .data$Lowess.x, 61 | y = .data$Lowess.y 62 | ), 63 | colour = "red", 64 | size = 0.5 65 | ) 66 | } 67 | 68 | # Add theme to plot 69 | if (theme == "bw") { 70 | plot <- plot + theme_bw() 71 | } else if (theme == "classic") { 72 | plot <- plot + theme_classic() 73 | } else if (theme == "gray" | theme == "grey") { 74 | plot <- plot + theme_grey() 75 | } 76 | 77 | # Set text size of title and axis labels, determine whether to include a title, 78 | # and return plot 79 | if (title.opt == TRUE) { 80 | plot + 81 | labs(title = "Residual Plot") + 82 | theme( 83 | plot.title = element_text(size = title.text.size, face = "bold"), 84 | axis.title = element_text(size = axis.text.size) 85 | ) 86 | } else if (title.opt == FALSE) { 87 | plot + theme(axis.title = element_text(size = axis.text.size)) 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /R/plot_boxplot.R: -------------------------------------------------------------------------------- 1 | # Boxplot of Residuals. 2 | 3 | # Function for creating a boxplot of the residuals 4 | plot_boxplot <- function( 5 | model, 6 | type, 7 | theme, 8 | axis.text.size, 9 | title.text.size, 10 | title.opt 11 | ) { 12 | 13 | ## Creation of Values to Plot ----------------------------------------------------- 14 | 15 | # Create a data frame with the residuals 16 | if (is.na(type)) { 17 | model_values <- 18 | data.frame( 19 | Residual = helper_resid(type = NA, model = model), 20 | Group = "" 21 | ) 22 | } else{ 23 | model_values <- 24 | data.frame( 25 | Residual = helper_resid(type = type, model = model), 26 | Group = "" 27 | ) 28 | } 29 | 30 | # Add an observation variable 31 | model_values$Observation <- 1:nrow(model_values) 32 | 33 | ## Creation of Labels ------------------------------------------------------------- 34 | 35 | # Call function to return appropriate residual label 36 | r_label <- helper_label(type = type, model = model) 37 | 38 | # Create a title for the plot based on r_label 39 | #title <- paste("Boxplot of", r_label) 40 | 41 | # Create labels for plotly 42 | Data <- helper_plotly_label(model) 43 | 44 | ## Creation of Plot --------------------------------------------------------------- 45 | 46 | # Create the boxplot of residuals 47 | plot <- 48 | ggplot( 49 | data = model_values, 50 | mapping = aes( 51 | x = .data$Group, 52 | y = .data$Residual, 53 | label = Data 54 | ) 55 | ) + 56 | geom_boxplot(width = .5) + 57 | geom_point(alpha = 0) + 58 | labs(x = " ", y = r_label) 59 | 60 | # Add theme to plot 61 | if (theme == "bw") { 62 | plot <- plot + theme_bw() 63 | } else if (theme == "classic") { 64 | plot <- plot + theme_classic() 65 | } else if (theme == "gray" | theme == "grey") { 66 | plot <- plot + theme_grey() 67 | } 68 | 69 | # Set text size of title and axis labels, determine whether to include 70 | # a title, and return plot 71 | if (title.opt == TRUE) { 72 | plot + 73 | labs(title = "Boxplot") + 74 | theme( 75 | plot.title = element_text(size = title.text.size, face = "bold"), 76 | axis.title = element_text(size = axis.text.size) 77 | ) 78 | } else if (title.opt == FALSE) { 79 | plot + theme(axis.title = element_text(size = axis.text.size)) 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /R/plot_constlev.R: -------------------------------------------------------------------------------- 1 | # Residual-Leverage plot. 2 | 3 | # Creates a plot of the residuals versus leverage from a model 4 | plot_constlev <- function( 5 | model, 6 | type, 7 | theme, 8 | axis.text.size, 9 | title.text.size, 10 | title.opt, 11 | alpha = alpha 12 | ) { 13 | 14 | ## Creation of Values to Plot ----------------------------------------------------- 15 | 16 | # Create a data frame with the factor values and standardized residuals based 17 | # on the type of model 18 | model_summary <- summary(model) 19 | n_factor_variables <- length(names(model$xlevels)) 20 | 21 | # Add first factor variable 22 | all_factors <- model$model[[2]] 23 | # if there are more than 1 factor variables, add them 24 | if (n_factor_variables > 1) { 25 | for (i in 3:(n_factor_variables + 1)) 26 | all_factors <- paste(all_factors, model$model[[i]], sep = ":") 27 | } 28 | 29 | # Create a data frame with the all_factors variable 30 | model_values <- data.frame(Variables = all_factors) 31 | 32 | # Add the standardized residuals to the plot 33 | if (class(model)[1] == "lm") { 34 | if (sum(hatvalues(model) == 1) > 0) { 35 | model_values$Std_Res <- 36 | suppressWarnings(helper_resid(model, type = "standardized")) 37 | } else { 38 | model_values$Std_Res <- 39 | helper_resid(model, type = "standardized") 40 | } 41 | } else if (class(model)[1] == "glm") { 42 | if (is.na(type) | 43 | type == "response" | 44 | type == "deviance" | 45 | type == "stand.deviance") { 46 | if (sum(hatvalues(model) == 1) > 0) { 47 | model_values$Std_Res <- 48 | suppressWarnings(helper_resid(model, type = "stand.deviance")) 49 | } else { 50 | model_values$Std_Res <- 51 | helper_resid(model, type = "stand.deviance") 52 | } 53 | } else if (type == "pearson" | type == "stand.pearson") { 54 | if (sum(hatvalues(model) == 1) > 0) { 55 | model_values$Std_Res <- 56 | suppressWarnings(helper_resid(model, type = "stand.pearson")) 57 | } else { 58 | model_values$Std_Res <- 59 | helper_resid(model, type = "stand.pearson") 60 | } 61 | } 62 | } 63 | 64 | # Compute the values for the lowess curve #Removed 65 | #model_values$Lowess.x <- lowess(x = model_values$Variables, y = model_values$Std_Res)$x 66 | #model_values$Lowess.y <- lowess(x = model_values$Variables, y = model_values$Std_Res)$y 67 | 68 | ## Creation of Labels ------------------------------------------------------------- 69 | 70 | # Call function to return appropriate residual label based on model type 71 | if (class(model)[1] == "lm") { 72 | r_label <- helper_label(type = "standardized", model) 73 | } else if (class(model)[1] == "glm") { 74 | if (is.na(type) | 75 | type == "response" | 76 | type == "deviance" | type == "stand.deviance") { 77 | r_label <- helper_label(type = "stand.deviance", model) 78 | } else if (type == "pearson" | type == "stand.pearson") { 79 | r_label <- helper_label(type = "stand.pearson", model) 80 | } 81 | } 82 | 83 | # Create labels for plotly 84 | Data <- helper_plotly_label(model) 85 | model_values$Data <- Data 86 | 87 | ## Creation of Plot --------------------------------------------------------------- 88 | # Create the constant leverage plot 89 | 90 | plot <- 91 | ggplot( 92 | data = model_values, 93 | mapping = aes( 94 | x = .data$Variables, 95 | y = .data$Std_Res 96 | ), 97 | na.rm = TRUE 98 | ) + 99 | geom_point( 100 | mapping = aes(group = Data), 101 | alpha = alpha 102 | ) + 103 | #geom_line(aes(x = {Lowess.x}, y = {Lowess.y}), color = "red", linewidth = 0.5) + 104 | geom_abline( 105 | slope = 0, 106 | intercept = 0, 107 | color = "blue", 108 | linewidth = 0.5 109 | ) + 110 | xlab("Factor Level Combinations") + 111 | ylab("Standardized Residuals") 112 | 113 | # Add theme to plot 114 | if (theme == "bw") { 115 | plot <- plot + theme_bw() 116 | } else if (theme == "classic") { 117 | plot <- plot + theme_classic() 118 | } else if (theme == "gray" | theme == "grey") { 119 | plot <- plot + theme_grey() 120 | } 121 | 122 | # Set text size of title and axis labels, determine whether to include a title, 123 | # and return plot 124 | if (title.opt == TRUE) { 125 | plot + 126 | labs(title = "Constant Leverage Plot") + 127 | theme( 128 | plot.title = element_text(size = title.text.size, face = "bold"), 129 | axis.title = element_text(size = axis.text.size) 130 | ) 131 | } else if (title.opt == FALSE) { 132 | plot + theme(axis.title = element_text(size = axis.text.size)) 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /R/plot_cookd.R: -------------------------------------------------------------------------------- 1 | # Cook's D Plot. 2 | 3 | # Creates a plot with the Cook's D values versus the observation number 4 | plot_cookd <- function( 5 | model, 6 | theme, 7 | axis.text.size, 8 | title.text.size, 9 | title.opt, 10 | alpha) { 11 | 12 | ## Creation of Values to Plot ----------------------------------------------- 13 | 14 | # Create a data frame with the Cook's D values and the observation numbers 15 | model_values <- 16 | data.frame( 17 | CooksD = round(cooks.distance(model), 3), 18 | Obs = 1:length(resid(model)) 19 | ) 20 | 21 | # Create the cutoff SAS uses with Cook's D 22 | cutoff_cookd <- 4 / length(resid(model)) 23 | 24 | # Obtain the leverage values 25 | Leverage <- hatvalues(model) 26 | 27 | # Determine if any of the leverage values are equal to 1 28 | cutoff <- 0.999999999 29 | one_lev <- sum(Leverage >= cutoff) > 0 30 | 31 | # IDs for observations over cutoff: 32 | IDs <- which(Leverage >= cutoff) 33 | 34 | # Alternative cutoff that could be used with Cook's D 35 | # k <- length(model$coefficients)-1 36 | # cutoff <- qf(.2, k+1, length(model$residuals)-k-1) 37 | 38 | ## Creation of Labels ------------------------------------------------------- 39 | 40 | # Create labels for plotly 41 | Data <- helper_plotly_label(model) 42 | 43 | ## Creation of Plot --------------------------------------------------------- 44 | 45 | # Create the Cook's D plot 46 | # Return a warning if any of the leverage values are equal to 1 and add 47 | # lines to plot 48 | if (one_lev) { 49 | warning( 50 | "Observation(s) with a leverage value of 1 are present. Point(s) 51 | have infinite Cook's D." 52 | ) 53 | plot <- 54 | ggplot( 55 | data = model_values, 56 | mapping = aes( 57 | x = .data$Obs, 58 | y = .data$CooksD, 59 | color = .data$CooksD, 60 | label = Data 61 | ) 62 | ) + 63 | geom_point(alpha = min(alpha * 2, 1)) + 64 | scale_color_gradient2( 65 | low = "#F0E442", 66 | mid = "#56B4E9", 67 | high = "#D55E00", 68 | na.value = "#D55E00", 69 | limits = c(0, 1), 70 | midpoint = cutoff_cookd, 71 | breaks = sort(c(0, cutoff_cookd, 0.5, 1)), 72 | labels = c(0, "4/n", 0.5, "\u2265 1") 73 | ) + #Wrong label for rare case of n < 8 74 | geom_segment( 75 | mapping = aes(xend = .data$Obs, yend = 0), 76 | color = "blue" 77 | ) + 78 | labs( 79 | x = "Observation Number", 80 | y = "Cook's D", 81 | colour = "Cook's D" 82 | ) + 83 | geom_hline( 84 | yintercept = cutoff_cookd, 85 | colour = "blue", 86 | linetype = 5 87 | ) + 88 | geom_hline( 89 | yintercept = 0, 90 | colour = "black" 91 | ) + 92 | geom_vline( 93 | xintercept = IDs, 94 | colour = "#D55E00", 95 | linetype = 2 96 | ) 97 | } else{ 98 | plot <- 99 | ggplot( 100 | data = model_values, 101 | mapping = aes( 102 | x = .data$Obs, 103 | y = .data$CooksD, 104 | color = .data$CooksD, 105 | label = Data 106 | ) 107 | ) + 108 | geom_point(alpha = min(alpha * 2, 1)) + 109 | scale_color_gradient2( 110 | low = "#F0E442", 111 | mid = "#56B4E9", 112 | high = "#D55E00", 113 | na.value = "#D55E00", 114 | limits = c(0, 1), 115 | midpoint = cutoff_cookd, 116 | breaks = sort(c(0, cutoff_cookd, 0.5, 1)), 117 | labels = c(0, "4/n", 0.5, "\u2265 1") 118 | ) + # Wrong label for rare case of n < 8 119 | geom_segment( 120 | mapping = aes(xend = .data$Obs, yend = 0), 121 | color = "blue" 122 | ) + 123 | labs( 124 | x = "Observation Number", 125 | y = "Cook's D" 126 | ) + 127 | geom_hline( 128 | yintercept = cutoff_cookd, 129 | colour = "blue", 130 | linetype = 5 131 | ) + 132 | geom_hline( 133 | yintercept = 0, 134 | colour = "black" 135 | ) 136 | } 137 | 138 | # Add theme to plot 139 | if (theme == "bw") { 140 | plot <- plot + theme_bw() 141 | } else if (theme == "classic") { 142 | plot <- plot + theme_classic() 143 | } else if (theme == "gray" | theme == "grey") { 144 | plot <- plot + theme_grey() 145 | } 146 | 147 | # Set text size of title and axis labels, determine whether to include a 148 | # title, and return plot without Cook's D color legend (not needed since 149 | # plotting Cook's D) 150 | if (title.opt == TRUE) { 151 | plot + 152 | labs(title = "Cook's D versus Index Plot") + 153 | theme( 154 | plot.title = element_text(size = title.text.size, face = "bold"), 155 | axis.title = element_text(size = axis.text.size), 156 | legend.pos = "none" 157 | ) 158 | } else if (title.opt == FALSE) { 159 | plot + 160 | theme( 161 | axis.title = element_text(size = axis.text.size), 162 | legend.pos = "none" 163 | ) 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /R/plot_hist.R: -------------------------------------------------------------------------------- 1 | # Histogram of Residuals. 2 | 3 | # Creates a histogram of the residuals from a model 4 | plot_hist <- function( 5 | model, 6 | type, 7 | bins, 8 | theme, 9 | axis.text.size, 10 | title.text.size, 11 | title.opt 12 | ) { 13 | 14 | ## Creation of Values to Plot ----------------------------------------------------- 15 | 16 | # If bins = NA, use default value of 30 17 | if (is.na(bins)) { 18 | bins <- 30 19 | } 20 | 21 | # Create a data frame with the residuals 22 | if (is.na(type)) { 23 | model_values <- 24 | data.frame(Residual = helper_resid(type = NA, model = model)) 25 | } else{ 26 | model_values <- 27 | data.frame(Residual = helper_resid(type = type, model = model)) 28 | } 29 | 30 | # # Steps to make sure any huge outliers are not cut off 31 | # if (min(model_values$Residual) < -4 * sd(model_values$Residual)){ 32 | # min_x <- NA 33 | # } else{ 34 | # min_x <- -4*sd(model_values$Residual) 35 | # } 36 | # if (max(model_values$Residual) > 4 * sd(model_values$Residual)){ 37 | # max_x <- NA 38 | # } else{ 39 | # max_x <- 4 * sd(model_values$Residual) 40 | # } 41 | 42 | grid_r <- 43 | seq( 44 | -4 * max(sd(model_values$Residual), 0.00001), 45 | 4 * max(sd(model_values$Residual), 0.00001), 46 | .01 47 | ) 48 | y <- 49 | dnorm( 50 | grid_r, 51 | mean = 0, 52 | sd = max(sd(model_values$Residual), 0.00001) 53 | ) 54 | d_data <- data.frame(grid_r, y) 55 | 56 | ## Creation of Labels ------------------------------------------------------------- 57 | 58 | # Call function to return appropriate residual label 59 | r_label <- helper_label(type, model) 60 | 61 | # Create a title for the plot based on r_label 62 | # title <- paste("Histogram of", r_label) 63 | 64 | sd_resid <- sd(model_values$Residual) 65 | 66 | # Call data for labels 67 | Data <- helper_plotly_label(model) 68 | model_values <- cbind(model_values, Data) 69 | model_values$y <- rep(0, nrow(model_values)) 70 | model_values$Resid <- model_values$Residual 71 | 72 | ## Creation of Plot --------------------------------------------------------------- 73 | 74 | # Create the histogram of residuals 75 | # if (is.na(min_x) & is.na(max_x)){ 76 | model_values$Residual_Density <- model_values$Residual 77 | 78 | plot <- 79 | ggplot( 80 | data = model_values, 81 | mapping = aes(x = .data$Residual) 82 | ) + 83 | geom_point( 84 | mapping = aes( 85 | x = .data$Resid, 86 | y = y, 87 | group = Data 88 | ), 89 | alpha = 0) + 90 | geom_histogram( 91 | mapping = aes( 92 | y = after_stat(.data$density), 93 | fill = after_stat(.data$count) 94 | ), 95 | color = "black", 96 | fill = "grey82", 97 | bins = bins 98 | ) + 99 | stat_function( 100 | fun = dnorm, 101 | color = "blue", 102 | args = list(mean = 0, sd = sd_resid) 103 | ) + 104 | geom_point( 105 | data = d_data, 106 | mapping = aes( 107 | x = grid_r, 108 | y = y 109 | ), 110 | alpha = 0) + 111 | labs( 112 | x = r_label, 113 | y = "Density" 114 | ) 115 | 116 | # } else{ 117 | # 118 | # # Data is not outside of 4*sd, so xlim is used 119 | # plot <- ggplot(model_values, aes(x = Residual)) + 120 | # geom_histogram(aes(y = ..density.., fill = ..count..), 121 | # color = "black", fill = "grey82", bins = bins) + 122 | # stat_function(fun = dnorm, color = "blue", 123 | # args = list(mean = 0, sd = sd_resid)) + 124 | # labs(x = r_label, y = "Density") + 125 | # xlim(c(min_x, max_x)) 126 | # 127 | # } 128 | 129 | # plot <- ggplot(model_values, aes(x = Residual)) + 130 | # geom_histogram(aes(y = ..density.., fill = ..count..), 131 | # color = "black", fill = "grey82", bins = bins) + 132 | # geom_line(data=d_data, aes(Residual,y),color = "blue") + 133 | # labs(x = r_label, y = "Density") 134 | 135 | # Add theme to plot 136 | if (theme == "bw") { 137 | plot <- plot + theme_bw() 138 | } else if (theme == "classic") { 139 | plot <- plot + theme_classic() 140 | } else if (theme == "gray" | theme == "grey") { 141 | plot <- plot + theme_grey() 142 | } 143 | 144 | # Set text size of title and axis labels, determine whether to include a title, 145 | # and return plot 146 | if (title.opt == TRUE) { 147 | plot + 148 | labs(title = "Histogram") + 149 | theme( 150 | plot.title = element_text(size = title.text.size, face = "bold"), 151 | axis.title = element_text(size = axis.text.size) 152 | ) 153 | } else if (title.opt == FALSE) { 154 | plot + theme(axis.title = element_text(size = axis.text.size)) 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /R/plot_index.R: -------------------------------------------------------------------------------- 1 | # Residual vs Index Plot. 2 | 3 | # Creates a residual vs index plot from a model 4 | plot_index <- function( 5 | model, 6 | type, 7 | smoother, 8 | theme, 9 | axis.text.size, 10 | title.text.size, 11 | title.opt, 12 | alpha 13 | ) { 14 | 15 | ## Creation of Values to Plot ----------------------------------------------------- 16 | 17 | # Create a data frame with the residuals 18 | if (is.na(type)) { 19 | model_values <- 20 | data.frame(Residual = helper_resid(type = NA, model = model)) 21 | } else{ 22 | model_values <- 23 | data.frame(Residual = helper_resid(type = type, model = model)) 24 | } 25 | 26 | # Create a variable for the observation number 27 | model_values$Observation <- 1:length(model_values$Residual) 28 | 29 | ## Creation of Labels ------------------------------------------------------------- 30 | 31 | # Call function to return appropriate residual label 32 | r_label <- helper_label(type, model) 33 | 34 | # Create labels for plotly 35 | Data <- helper_plotly_label(model) 36 | 37 | ## Creation of Plot --------------------------------------------------------------- 38 | 39 | # Create the residual plot 40 | plot <- 41 | ggplot( 42 | data = model_values, 43 | mapping = aes( 44 | x = .data$Observation, 45 | y = .data$Residual, 46 | label = Data 47 | ) 48 | ) + 49 | geom_point(alpha = alpha) + 50 | geom_abline( 51 | slope = 0, 52 | intercept = 0, 53 | color = "blue" 54 | ) + 55 | labs( 56 | x = "Observation Number", 57 | y = r_label 58 | ) 59 | 60 | # If smoother is set to true, add it to the plot 61 | if (smoother == TRUE) { 62 | plot <- plot + 63 | geom_smooth( 64 | method = "loess", 65 | se = FALSE, 66 | color = "red", 67 | linewidth = 0.5, 68 | formula = 'y ~ x' 69 | ) 70 | } 71 | 72 | # Add theme to plot 73 | if (theme == "bw") { 74 | plot <- plot + theme_bw() 75 | } else if (theme == "classic") { 76 | plot <- plot + theme_classic() 77 | } else if (theme == "gray" | theme == "grey") { 78 | plot <- plot + theme_grey() 79 | } 80 | 81 | # Set text size of title and axis labels, determine whether to include a title, 82 | # and return plot 83 | if (title.opt == TRUE) { 84 | plot + 85 | labs(title = "Index Plot") + 86 | theme( 87 | plot.title = element_text(size = title.text.size, face = "bold"), 88 | axis.title = element_text(size = axis.text.size) 89 | ) 90 | } else if (title.opt == FALSE) { 91 | plot + theme(axis.title = element_text(size = axis.text.size)) 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /R/plot_ls.R: -------------------------------------------------------------------------------- 1 | # Location-Scale Plot. 2 | 3 | # Creates a location-scale plot with the square root of the standardized residuals 4 | # versus predicted values from a model 5 | plot_ls <- function( 6 | model, 7 | type, 8 | smoother, 9 | theme, 10 | axis.text.size, 11 | title.text.size, 12 | title.opt, 13 | alpha 14 | ) { 15 | 16 | ## Creation of Values to Plot ----------------------------------------------------- 17 | 18 | # Create a data frame with the square root of the standardized residuals and 19 | # predicted values based on the model type 20 | if (class(model)[1] == "lm") { 21 | model_values <- 22 | data.frame( 23 | Sqrt_Std_Res = sqrt(abs(helper_resid(type = "standardized", model = model))), 24 | Prediction = fitted(model) 25 | ) 26 | } else if (class(model)[1] == "glm") { 27 | if (is.na(type) | type == "response" | 28 | type == "deviance" |type == "stand.deviance") { 29 | model_values <- 30 | data.frame( 31 | Sqrt_Std_Res = sqrt(abs(helper_resid(type = "stand.deviance", model = model))), 32 | Prediction = fitted(model)) 33 | } else if (type == "pearson" | type == "stand.pearson") { 34 | model_values <- 35 | data.frame( 36 | Sqrt_Std_Res = sqrt(abs(helper_resid(type = "stand.pearson", model = model))), 37 | Prediction = fitted(model) 38 | ) 39 | } 40 | } 41 | 42 | # Compute the values for the lowess curve: old version used lowess, new version using loess 43 | # model_values$Lowess.x <- lowess(x = model_values$Prediction, y = model_values$Sqrt_Std_Res)$x 44 | # model_values$Lowess.y <- lowess(x = model_values$Prediction, y = model_values$Sqrt_Std_Res)$y 45 | 46 | ## Creation of Labels ------------------------------------------------------------- 47 | 48 | # Create labels for plotly 49 | Data <- helper_plotly_label(model) 50 | 51 | ## Creation of Plot --------------------------------------------------------------- 52 | 53 | # Create the location-scale plot - labels are adjusted based on the model type 54 | if (class(model)[1] == "lm") { 55 | # Location-scale plot for lm model 56 | plot <- 57 | ggplot( 58 | data = model_values, 59 | mapping = aes( 60 | x = .data$Prediction, 61 | y = .data$Sqrt_Std_Res, 62 | label = Data 63 | ) 64 | ) + 65 | geom_point(alpha = alpha) + 66 | labs( 67 | x = "Predicted Values", 68 | y = expression(sqrt(abs(" Standardized Residuals "))) 69 | ) + 70 | expand_limits(y = 0) 71 | } else if (class(model)[1] == "glm") { 72 | # Location-scale plot for glm model with deviance residuals 73 | if (is.na(type) | 74 | type == "response" | 75 | type == "deviance" | type == "stand.deviance") { 76 | plot <- 77 | ggplot( 78 | data = model_values, 79 | mapping = aes( 80 | x = .data$Prediction, 81 | y = .data$Sqrt_Std_Res, 82 | label = Data 83 | ) 84 | ) + 85 | geom_point(alpha = alpha) + 86 | labs( 87 | x = "Predicted Values", 88 | y = expression(sqrt(abs(" Standardized Deviance Residuals "))) 89 | ) + 90 | expand_limits(y = 0) 91 | 92 | # Location-scale plot for glm model with Pearson residuals 93 | } else if (type == "pearson" | type == "stand.pearson") { 94 | plot <- 95 | ggplot( 96 | data = model_values, 97 | mapping = aes( 98 | x = .data$Prediction, 99 | y = .data$Sqrt_Std_Res, 100 | label = Data 101 | ) 102 | ) + 103 | geom_point(alpha = alpha) + 104 | labs( 105 | x = "Predicted Values", 106 | y = expression(sqrt(abs(" Standardized Pearson Residuals "))) 107 | ) + 108 | expand_limits(y = 0) 109 | } 110 | } 111 | 112 | # If smoother is set to true, do not add it to the plot 113 | if (smoother == TRUE) { 114 | plot <- plot #+ 115 | # geom_smooth( 116 | # method = "loess", 117 | # se = FALSE, 118 | # color = "red", 119 | # linewidth = 0.5, 120 | # formula = 'y ~ x' 121 | # ) 122 | } 123 | 124 | # Add theme to plot 125 | if (theme == "bw") { 126 | plot <- plot + theme_bw() 127 | } else if (theme == "classic") { 128 | plot <- plot + theme_classic() 129 | } else if (theme == "gray" | theme == "grey") { 130 | plot <- plot + theme_grey() 131 | } 132 | 133 | # Set text size of title and axis labels, determine whether to include a title, 134 | # and return plot 135 | if (title.opt == TRUE) { 136 | plot + 137 | labs(title = "Location-Scale Plot") + 138 | theme( 139 | plot.title = element_text(size = title.text.size, face = "bold"), 140 | axis.title = element_text(size = axis.text.size) 141 | ) 142 | } else if (title.opt == FALSE) { 143 | plot + theme(axis.title = element_text(size = axis.text.size)) 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /R/plot_qq.R: -------------------------------------------------------------------------------- 1 | # Q-Q Plot. 2 | 3 | # Creates a Q-Q plot on the residuals from a model 4 | plot_qq <- function( 5 | model, 6 | type, 7 | theme, 8 | axis.text.size, 9 | title.text.size, 10 | title.opt, 11 | qqline, 12 | qqbands, 13 | alpha 14 | ) { 15 | 16 | ## Creation of Values to Plot ----------------------------------------------------- 17 | 18 | # Compute the residuals and put in a dataframe 19 | if (is.na(type)) { 20 | model_values <- 21 | data.frame(Residual = helper_resid(type = NA, model = model)) 22 | } else{ 23 | model_values <- 24 | data.frame(Residual = helper_resid(type = type, model = model)) 25 | } 26 | 27 | ## Creation of Labels ------------------------------------------------------------- 28 | 29 | # Call function to return appropriate residual label 30 | r_label <- helper_label(type, model) 31 | 32 | # Create a title for the plot based on r_label 33 | #title <- paste("Q-Q Plot of", r_label) 34 | 35 | # Create labels for plotly 36 | data_add <- helper_plotly_label(model) 37 | model_values <- cbind(model_values, data_add) 38 | names(model_values)[which(names(model_values) == "data_add")] <- "Data" 39 | 40 | ## Creation of Plot --------------------------------------------------------------- 41 | model_values <- model_values[order(model_values$Residual), ] 42 | plot <- 43 | ggplot( 44 | data = model_values, 45 | mapping = aes( 46 | sample = .data$Residual, 47 | label = .data$Data 48 | ) 49 | ) + 50 | stat_qq_point(alpha = alpha) + 51 | labs( 52 | x = "Theoretical Quantiles", 53 | y = "Sample Quantiles" 54 | ) 55 | 56 | plot_data <- ggplot_build(plot) 57 | model_values$Theoretical <- plot_data[[1]][[1]]$theoretical 58 | 59 | #Residual for using for qq: 'Residual' is for label 60 | model_values$Residual_Plot <- model_values$Residual 61 | # Create the qq plot 62 | if (qqbands == TRUE) { 63 | # Add bands if requested 64 | plot <- 65 | ggplot( 66 | data = model_values, 67 | mapping = aes( 68 | sample = .data$Residual_Plot, 69 | label = .data$Data 70 | ) 71 | ) + 72 | stat_qq_band() + 73 | stat_qq_point(alpha = alpha) + 74 | labs( 75 | x = "Theoretical Quantiles", 76 | y = "Sample Quantiles" 77 | ) + 78 | coord_fixed() 79 | 80 | } else { 81 | # Don't add bands 82 | plot <- 83 | ggplot( 84 | data = model_values, 85 | mapping = aes( 86 | sample = .data$Residual_Plot, 87 | label = .data$Data 88 | ) 89 | ) + 90 | stat_qq_point(alpha = alpha) + 91 | geom_point( 92 | mapping = aes( 93 | x = .data$Theoretical, 94 | y = .data$Residual 95 | ), 96 | alpha = alpha 97 | ) + 98 | labs( 99 | x = "Theoretical Quantiles", 100 | y = "Sample Quantiles" 101 | ) + 102 | coord_fixed() 103 | 104 | } 105 | 106 | # Add a line if requested 107 | if (qqline == TRUE) { 108 | plot <- plot + stat_qq_line(color = "blue", linewidth = .5) 109 | } 110 | 111 | # Add theme to plot 112 | if (theme == "bw") { 113 | plot <- plot + theme_bw() 114 | } else if (theme == "classic") { 115 | plot <- plot + theme_classic() 116 | } else if (theme == "gray" | theme == "grey") { 117 | plot <- plot + theme_grey() 118 | } 119 | 120 | # Set text size of title and axis labels, determine whether to include a title, 121 | # and return plot 122 | if (title.opt == TRUE) { 123 | plot + 124 | labs(title = "Q-Q Plot") + 125 | theme( 126 | plot.title = element_text(size = title.text.size, face = "bold"), 127 | axis.title = element_text(size = axis.text.size) 128 | ) 129 | } else if (title.opt == FALSE) { 130 | plot + 131 | theme(axis.title = element_text(size = axis.text.size)) 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /R/plot_resid.R: -------------------------------------------------------------------------------- 1 | # Residual Plot. 2 | 3 | # Creates a residual plot with residuals versus predicted values from a model 4 | plot_resid <- function( 5 | model, 6 | type, 7 | smoother, 8 | theme, 9 | axis.text.size, 10 | title.text.size, 11 | title.opt, 12 | alpha 13 | ) { 14 | 15 | ## Creation of Values to Plot ----------------------------------------------------- 16 | 17 | # Create a data frame with the residuals 18 | if (is.na(type)) { 19 | model_values <- 20 | data.frame( 21 | Residual = helper_resid(type = NA, model = model), 22 | Prediction = fitted(model) 23 | ) 24 | } else{ 25 | model_values <- 26 | data.frame( 27 | Residual = helper_resid(type = type, model = model), 28 | Prediction = fitted(model) 29 | ) 30 | } 31 | 32 | ## Creation of Labels ------------------------------------------------------------- 33 | 34 | # Call function to return appropriate residual label 35 | r_label <- helper_label(type, model) 36 | 37 | # Create a title for the plot based on r_label 38 | #title <- paste(r_label, "Plot") 39 | 40 | # Create labels for plotly 41 | Data <- helper_plotly_label(model) 42 | 43 | ## Creation of Plot --------------------------------------------------------------- 44 | 45 | # Create the residual plot 46 | plot <- 47 | ggplot( 48 | data = model_values, 49 | mapping = aes( 50 | x = .data$Prediction, 51 | y = .data$Residual, 52 | label = Data 53 | ) 54 | ) + 55 | geom_point(alpha = alpha) + 56 | geom_abline( 57 | slope = 0, 58 | intercept = 0, 59 | color = "blue" 60 | ) + 61 | labs( 62 | x = "Predicted Values", 63 | y = r_label 64 | ) 65 | 66 | # If smoother is set to true, add it to the plot 67 | if (smoother == TRUE) { 68 | plot <- plot + 69 | geom_smooth( 70 | method = "loess", 71 | se = FALSE, 72 | color = "red", 73 | linewidth = 0.5, 74 | formula = 'y ~ x' 75 | ) 76 | } 77 | 78 | # Add theme to plot 79 | if (theme == "bw") { 80 | plot <- plot + theme_bw() 81 | } else if (theme == "classic") { 82 | plot <- plot + theme_classic() 83 | } else if (theme == "gray" | theme == "grey") { 84 | plot <- plot + theme_grey() 85 | } 86 | 87 | # Set text size of title and axis labels, determine whether to include a title, 88 | # and return plot 89 | if (title.opt == TRUE) { 90 | plot + 91 | labs(title = "Residual vs Fitted Plot") + 92 | theme( 93 | plot.title = element_text(size = title.text.size, face = "bold"), 94 | axis.title = element_text(size = axis.text.size) 95 | ) 96 | } else if (title.opt == FALSE) { 97 | plot + theme(axis.title = element_text(size = axis.text.size)) 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /R/plot_yvp.R: -------------------------------------------------------------------------------- 1 | # Response versus predicted plot. 2 | 3 | # Creates a plot of the response variable versus the predicted values 4 | plot_yvp <- function( 5 | model, 6 | theme, 7 | axis.text.size, 8 | title.text.size, 9 | title.opt, 10 | alpha 11 | ) { 12 | 13 | ## Creation of Values to Plot ----------------------------------------------------- 14 | 15 | # Create a data frame with the predicted values and response variable 16 | # based on the model type 17 | if (class(model)[1] == "glm") { 18 | if (model$family[[1]] == "binomial") { 19 | model_values <- 20 | data.frame( 21 | Predicted = fitted(model), 22 | Response = helper_glm_actual(model) 23 | ) 24 | names(model_values) <- c("Predicted", "Response") 25 | y_label <- "Actual Proportions" 26 | } else{ 27 | model_values <- 28 | data.frame( 29 | Predicted = fitted(model), 30 | Response = model.frame(model)[[1]] 31 | ) 32 | y_label <- names(model.frame(model)[1]) 33 | } 34 | } else if (class(model)[1] == "glmerMod") { 35 | if (model@resp$family[[1]] == "binomial") { 36 | model_values <- 37 | data.frame( 38 | Predicted = fitted(model), 39 | Response = helper_glm_actual(model) 40 | ) 41 | names(model_values) <- c("Predicted", "Response") 42 | y_label <- "Actual Proportions" 43 | } else{ 44 | model_values <- 45 | data.frame( 46 | Predicted = fitted(model), 47 | Response = model.frame(model)[[1]] 48 | ) 49 | y_label <- names(model.frame(model)[1]) 50 | } 51 | } else if (class(model)[1] == "lme") { 52 | model_values <- 53 | data.frame( 54 | Predicted = fitted(model), 55 | Response = model$data[[1]] 56 | ) 57 | y_label <- names(model$data[1]) 58 | } else{ 59 | model_values <- 60 | data.frame( 61 | Predicted = fitted(model), 62 | Response = model.frame(model)[[1]] 63 | ) 64 | y_label <- names(model.frame(model)[1]) 65 | } 66 | 67 | ## Creation of Labels ------------------------------------------------------------- 68 | 69 | # Create labels for plotly 70 | Data <- helper_plotly_label(model) 71 | 72 | ## Creation of Plot --------------------------------------------------------------- 73 | 74 | # Create the plot of response variable versus predicted values 75 | plot <- 76 | ggplot( 77 | data = model_values, 78 | mapping = aes( 79 | x = .data$Predicted, 80 | y = .data$Response, 81 | label = Data 82 | ) 83 | ) + 84 | geom_point(alpha = alpha) + 85 | geom_abline( 86 | slope = 1, 87 | intercept = 0, 88 | color = "blue" 89 | ) + 90 | coord_fixed() + 91 | labs( 92 | x = "Predicted Values", 93 | y = y_label 94 | ) 95 | 96 | # Add theme to plot 97 | if (theme == "bw") { 98 | plot <- plot + theme_bw() 99 | } else if (theme == "classic") { 100 | plot <- plot + theme_classic() 101 | } else if (theme == "gray" | theme == "grey") { 102 | plot <- plot + theme_grey() 103 | } 104 | 105 | # Set text size of title and axis labels, determine whether to include a title, 106 | # and return plot 107 | if (title.opt == TRUE) { 108 | plot + 109 | labs(title = "Response vs Predicted") + 110 | theme( 111 | plot.title = element_text(size = title.text.size, face = "bold"), 112 | axis.title = element_text(size = axis.text.size) 113 | ) 114 | } else if (title.opt == FALSE) { 115 | plot + theme(axis.title = element_text(size = axis.text.size)) 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: rmarkdown::github_document 3 | always_allow_html: yes 4 | --- 5 | 6 | ```{r setup, include = FALSE} 7 | knitr::opts_chunk$set( 8 | echo = TRUE, 9 | warning = FALSE, 10 | message = FALSE, 11 | fig.path = "inst/figures/readme-" 12 | ) 13 | ``` 14 | 15 | # ggResidpanel 16 | 17 | 18 | [![CRAN status](https://www.r-pkg.org/badges/version/ggResidpanel)](https://CRAN.R-project.org/package=ggResidpanel) 19 | [![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) 20 | [![R-CMD-check](https://github.com/goodekat/ggResidpanel/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/goodekat/ggResidpanel/actions/workflows/R-CMD-check.yaml) 21 | [![downloads](https://cranlogs.r-pkg.org/badges/ggResidpanel)](https://cran.rstudio.com/web/packages/ggResidpanel/index.html) 22 | [![Codecov test coverage](https://codecov.io/gh/goodekat/ggResidpanel/graph/badge.svg)](https://app.codecov.io/gh/goodekat/ggResidpanel) 23 | 24 | 25 | ggResidpanel is an R package for creating panels of diagnostic plots for a model using ggplot2 and interactive versions of the plots using plotly. 26 | 27 | ## Installation 28 | 29 | This is the current development version of ggResidpanel. Install the development version from GitHub or an older version from CRAN. 30 | 31 | ```{r, eval = FALSE} 32 | # Installs the development version of ggResidpanel from GitHub 33 | remotes::install_github("goodekat/ggResidpanel") 34 | 35 | # Installs ggResidpanel from CRAN 36 | install.packages("ggResidpanel") 37 | ``` 38 | 39 | Load the ggResidpanel package. 40 | 41 | ```{r} 42 | # Load the library 43 | library(ggResidpanel) 44 | ``` 45 | 46 | ## Learn More 47 | 48 | Here are some resources for learning how to use ggResidpanel: 49 | 50 | - [Introduction Vignette](https://goodekat.github.io/ggResidpanel/articles/introduction.html) 51 | - [Tutorial and User Manual](https://goodekat.github.io/ggResidpanel-tutorial/tutorial.html) 52 | 53 | ## Overview and Examples 54 | 55 | The package provides five functions that allow the user to assess diagnostic plots from a model. These functions are: 56 | 57 | - `resid_panel`: Creates a panel of diagnostic plots of the residuals from a model 58 | - `resid_interact`: Creates an interactive panel of diagnostic plots of the residuals form a model 59 | - `resid_xpanel`: Creates a panel of diagnostic plots of the predictor variables 60 | - `resid_compare`: Creates a panel of diagnostic plots from multiple models 61 | - `resid_auxpanel`: Creates a panel of diagnostic plots for model types not included in the package 62 | 63 | Currently, ggResidpanel allows the first four functions listed above to work with models fit using the functions of `lm`, `glm`, `lme` (from nlme), and `lmer` or `glmer` (from lme4 or fit using lmerTest). Each of these functions is applied below to show the panel that is output from the function. The functions have multiple input options such as the formatting options of `scale`, `theme`, `axis.text.size`, `title.text.size`, and `title.opt`. 64 | 65 | The `penguins` data used in the examples below is included in ggResidpanel. 66 | 67 | ```{r} 68 | str(penguins) 69 | ``` 70 | 71 | 72 | #### `resid_panel` 73 | 74 | This function creates a panel of residual diagnostic plots given a model. It allows the user to select a panel of plots from the options in the package or create their own panel by selecting from the plots available for this function. 75 | 76 | ```{r} 77 | # Fit a model 78 | penguin_model <- lme4::lmer(heartrate ~ depth + duration + (1|bird), data = penguins) 79 | 80 | # Create the default panel of plots 81 | resid_panel(penguin_model) 82 | 83 | # Create a pancel with residual, qq, and yvp plots, add 95% confidence interval 84 | # bands to the qq-plot, and change the theme to classic 85 | resid_panel(penguin_model, plots = c("resid", "qq", "yvp"), 86 | qqbands = TRUE, theme = "classic") 87 | 88 | # Create a panel with all plots available for a model fit using lmer 89 | resid_panel(penguin_model, plots = "all") 90 | ``` 91 | 92 | #### `resid_interact` 93 | 94 | This function creates interactive versions of residual diagnostic plot panels given a model. Similar to `resid_panel`, it allows the user to select a panel of plots from the options in the package or to create their own panel by selecting from the plots available for this function. 95 | 96 | ```{r, eval = FALSE} 97 | # Create an interactive panel of the default diagnostic plots 98 | resid_interact(penguin_model) 99 | ``` 100 | 101 | ![](inst/figures/interact.gif) 102 | 103 | #### `resid_xpanel` 104 | 105 | This function creates a panel of plots of the residuals or response variable versus the predictor (x) variables in the model. 106 | 107 | ```{r} 108 | # Create a panel of plots of the residuals versus the predictor variables 109 | resid_xpanel(penguin_model, jitter.width = 0.1) 110 | 111 | # Create a panel of plots of the response variable versus the predictor variables 112 | resid_xpanel(penguin_model, yvar = "response", jitter.width = 0.1) 113 | ``` 114 | 115 | #### `resid_compare` 116 | 117 | This function creates a panel of residual diagnostic plots given a list of models. This allows the user to compare the diagnostic plots from multiple models. 118 | 119 | ```{r} 120 | # Fit the model with a log transformation of the response variable and a 121 | # quadratic term for duration 122 | penguin_model_log2 <- lme4::lmer(log(heartrate) ~ depth + duration + I(duration^2) + (1|bird), 123 | data = penguins) 124 | 125 | # Plot the residual and normal quantile plots for the two models 126 | resid_compare(list(penguin_model, penguin_model_log2), plots = c("resid", "qq")) 127 | ``` 128 | 129 | #### `resid_auxpanel` 130 | 131 | This function creates a panel of residual diagnostic plots given inputs of residuals and fitted values to use for models not accepted by `resid_panel`. Users can select from panel options in the package or create their own panel from the plots available for this function. 132 | 133 | ```{r} 134 | # Fit a regression tree to the penguins data 135 | penguin_tree <- rpart::rpart(heartrate ~ depth + duration, data = penguins) 136 | 137 | # Obtain the predictions from the model on the observed data 138 | penguin_tree_pred <- predict(penguin_tree) 139 | 140 | # Obtain the residuals from the model 141 | penguin_tree_resid <- penguins$heartrate - penguin_tree_pred 142 | 143 | # Create a panel with the residual and index plot 144 | resid_auxpanel(residuals = penguin_tree_resid, 145 | predicted = penguin_tree_pred, 146 | plots = c("resid", "index")) 147 | ``` 148 | 149 | ```{r echo = FALSE, results = FALSE} 150 | # copy static figures to docs folder 151 | file.copy("./README_files/", "./docs", overwrite = TRUE, recursive = TRUE) 152 | ``` 153 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # ggResidpanel 3 | 4 | 5 | 6 | [![CRAN 7 | status](https://www.r-pkg.org/badges/version/ggResidpanel)](https://CRAN.R-project.org/package=ggResidpanel) 8 | [![Lifecycle: 9 | stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) 10 | [![R-CMD-check](https://github.com/goodekat/ggResidpanel/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/goodekat/ggResidpanel/actions/workflows/R-CMD-check.yaml) 11 | [![downloads](https://cranlogs.r-pkg.org/badges/ggResidpanel)](https://cran.rstudio.com/web/packages/ggResidpanel/index.html) 12 | [![Codecov test 13 | coverage](https://codecov.io/gh/goodekat/ggResidpanel/graph/badge.svg)](https://app.codecov.io/gh/goodekat/ggResidpanel) 14 | 15 | 16 | ggResidpanel is an R package for creating panels of diagnostic plots for 17 | a model using ggplot2 and interactive versions of the plots using 18 | plotly. 19 | 20 | ## Installation 21 | 22 | This is the current development version of ggResidpanel. Install the 23 | development version from GitHub or an older version from CRAN. 24 | 25 | ``` r 26 | # Installs the development version of ggResidpanel from GitHub 27 | remotes::install_github("goodekat/ggResidpanel") 28 | 29 | # Installs ggResidpanel from CRAN 30 | install.packages("ggResidpanel") 31 | ``` 32 | 33 | Load the ggResidpanel package. 34 | 35 | ``` r 36 | # Load the library 37 | library(ggResidpanel) 38 | ``` 39 | 40 | ## Learn More 41 | 42 | Here are some resources for learning how to use ggResidpanel: 43 | 44 | - [Introduction 45 | Vignette](https://goodekat.github.io/ggResidpanel/articles/introduction.html) 46 | - [Tutorial and User 47 | Manual](https://goodekat.github.io/ggResidpanel-tutorial/tutorial.html) 48 | 49 | ## Overview and Examples 50 | 51 | The package provides five functions that allow the user to assess 52 | diagnostic plots from a model. These functions are: 53 | 54 | - `resid_panel`: Creates a panel of diagnostic plots of the residuals 55 | from a model 56 | - `resid_interact`: Creates an interactive panel of diagnostic plots of 57 | the residuals form a model 58 | - `resid_xpanel`: Creates a panel of diagnostic plots of the predictor 59 | variables 60 | - `resid_compare`: Creates a panel of diagnostic plots from multiple 61 | models 62 | - `resid_auxpanel`: Creates a panel of diagnostic plots for model types 63 | not included in the package 64 | 65 | Currently, ggResidpanel allows the first four functions listed above to 66 | work with models fit using the functions of `lm`, `glm`, `lme` (from 67 | nlme), and `lmer` or `glmer` (from lme4 or fit using lmerTest). Each of 68 | these functions is applied below to show the panel that is output from 69 | the function. The functions have multiple input options such as the 70 | formatting options of `scale`, `theme`, `axis.text.size`, 71 | `title.text.size`, and `title.opt`. 72 | 73 | The `penguins` data used in the examples below is included in 74 | ggResidpanel. 75 | 76 | ``` r 77 | str(penguins) 78 | ``` 79 | 80 | ## 'data.frame': 125 obs. of 4 variables: 81 | ## $ heartrate: num 88.8 103.4 97.4 85.3 60.6 ... 82 | ## $ depth : num 5 9 22 25.5 30.5 32.5 38 32 6 10.5 ... 83 | ## $ duration : num 1.05 1.18 1.92 3.47 7.08 ... 84 | ## $ bird : Factor w/ 9 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ... 85 | 86 | #### `resid_panel` 87 | 88 | This function creates a panel of residual diagnostic plots given a 89 | model. It allows the user to select a panel of plots from the options in 90 | the package or create their own panel by selecting from the plots 91 | available for this function. 92 | 93 | ``` r 94 | # Fit a model 95 | penguin_model <- lme4::lmer(heartrate ~ depth + duration + (1|bird), data = penguins) 96 | 97 | # Create the default panel of plots 98 | resid_panel(penguin_model) 99 | ``` 100 | 101 | ![](inst/figures/readme-unnamed-chunk-4-1.png) 102 | 103 | ``` r 104 | # Create a pancel with residual, qq, and yvp plots, add 95% confidence interval 105 | # bands to the qq-plot, and change the theme to classic 106 | resid_panel(penguin_model, plots = c("resid", "qq", "yvp"), 107 | qqbands = TRUE, theme = "classic") 108 | ``` 109 | 110 | ![](inst/figures/readme-unnamed-chunk-4-2.png) 111 | 112 | ``` r 113 | # Create a panel with all plots available for a model fit using lmer 114 | resid_panel(penguin_model, plots = "all") 115 | ``` 116 | 117 | ![](inst/figures/readme-unnamed-chunk-4-3.png) 118 | 119 | #### `resid_interact` 120 | 121 | This function creates interactive versions of residual diagnostic plot 122 | panels given a model. Similar to `resid_panel`, it allows the user to 123 | select a panel of plots from the options in the package or to create 124 | their own panel by selecting from the plots available for this function. 125 | 126 | ``` r 127 | # Create an interactive panel of the default diagnostic plots 128 | resid_interact(penguin_model) 129 | ``` 130 | 131 | ![](inst/figures/interact.gif) 132 | 133 | #### `resid_xpanel` 134 | 135 | This function creates a panel of plots of the residuals or response 136 | variable versus the predictor (x) variables in the model. 137 | 138 | ``` r 139 | # Create a panel of plots of the residuals versus the predictor variables 140 | resid_xpanel(penguin_model, jitter.width = 0.1) 141 | ``` 142 | 143 | ![](inst/figures/readme-unnamed-chunk-6-1.png) 144 | 145 | ``` r 146 | # Create a panel of plots of the response variable versus the predictor variables 147 | resid_xpanel(penguin_model, yvar = "response", jitter.width = 0.1) 148 | ``` 149 | 150 | ![](inst/figures/readme-unnamed-chunk-6-2.png) 151 | 152 | #### `resid_compare` 153 | 154 | This function creates a panel of residual diagnostic plots given a list 155 | of models. This allows the user to compare the diagnostic plots from 156 | multiple models. 157 | 158 | ``` r 159 | # Fit the model with a log transformation of the response variable and a 160 | # quadratic term for duration 161 | penguin_model_log2 <- lme4::lmer(log(heartrate) ~ depth + duration + I(duration^2) + (1|bird), 162 | data = penguins) 163 | 164 | # Plot the residual and normal quantile plots for the two models 165 | resid_compare(list(penguin_model, penguin_model_log2), plots = c("resid", "qq")) 166 | ``` 167 | 168 | ![](inst/figures/readme-unnamed-chunk-7-1.png) 169 | 170 | #### `resid_auxpanel` 171 | 172 | This function creates a panel of residual diagnostic plots given inputs 173 | of residuals and fitted values to use for models not accepted by 174 | `resid_panel`. Users can select from panel options in the package or 175 | create their own panel from the plots available for this function. 176 | 177 | ``` r 178 | # Fit a regression tree to the penguins data 179 | penguin_tree <- rpart::rpart(heartrate ~ depth + duration, data = penguins) 180 | 181 | # Obtain the predictions from the model on the observed data 182 | penguin_tree_pred <- predict(penguin_tree) 183 | 184 | # Obtain the residuals from the model 185 | penguin_tree_resid <- penguins$heartrate - penguin_tree_pred 186 | 187 | # Create a panel with the residual and index plot 188 | resid_auxpanel(residuals = penguin_tree_resid, 189 | predicted = penguin_tree_pred, 190 | plots = c("resid", "index")) 191 | ``` 192 | 193 | ![](inst/figures/readme-unnamed-chunk-8-1.png) 194 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local OS X (x86_64-apple-darwin15.6.0 (64-bit)), R 3.6.0 3 | * Fedora Linux, R-devel, clang, gfortran (R-hub) 4 | * win-builder (devel) 5 | 6 | ## R CMD check results 7 | There were no ERRORs or WARNINGs. 8 | 9 | There was 1 NOTE (from Fedora Linux and win-builder): 10 | 11 | * checking CRAN incoming feasibility ... NOTE 12 | Maintainer: ‘Katherine Goode ’ 13 | 14 | New submission 15 | 16 | Possibly mis-spelled words in DESCRIPTION: 17 | ggplot (9:11) 18 | plotly (9:23) 19 | 20 | I am not concerned about this since the words that it believes are mis-spelled are referring to R packages. 21 | 22 | ## Downstream dependencies 23 | There are currently no downstream dependencies for this package -------------------------------------------------------------------------------- /data/penguins.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/data/penguins.rda -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • ggResidpanel 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 |
31 |
73 | 74 | 75 | 76 | 77 |
78 |
79 | 82 | 83 | Content not found. Please use links in the navbar. 84 | 85 |
86 | 87 | 91 | 92 |
93 | 94 | 95 | 96 |
100 | 101 |
102 |

103 |

Site built with pkgdown 2.0.1.

104 |
105 | 106 |
107 |
108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | License • ggResidpanel 6 | 7 | 8 |
9 |
44 | 45 | 46 | 47 |
48 |
49 | 52 | 53 |
YEAR: 2019
54 | COPYRIGHT HOLDER: Katherine J Goode
55 | 
56 | 57 |
58 | 59 | 62 | 63 |
64 | 65 | 66 | 67 |
70 | 71 |
72 |

Site built with pkgdown 2.0.1.

73 |
74 | 75 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /docs/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /docs/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | Articles • ggResidpanel 6 | 7 | 8 |
9 |
44 | 45 | 46 | 47 |
48 |
49 | 52 | 53 |
54 |

All vignettes

55 |

56 | 57 |
An Introduction to ggResidpanel
58 |
59 |
60 |
61 |
62 | 63 | 64 |
67 | 68 |
69 |

Site built with pkgdown 2.0.1.

70 |
71 | 72 |
73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/crosstalk-1.1.1/css/crosstalk.css: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-14-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-14-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-17-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-17-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/articles/introduction_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/introduction_files/plotly-htmlwidgets-css-1.57.1/plotly-htmlwidgets.css: -------------------------------------------------------------------------------- 1 | /* 2 | just here so that plotly works 3 | correctly with ioslides. 4 | see https://github.com/ropensci/plotly/issues/463 5 | */ 6 | 7 | slide:not(.current) .plotly.html-widget{ 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | Authors and Citation • ggResidpanel 6 | 7 | 8 |
9 |
44 | 45 | 46 | 47 |
48 |
49 |
50 | 53 | 54 | 55 |
  • 56 |

    Katherine Goode. Author, maintainer. 57 |

    58 |
  • 59 |
  • 60 |

    Kathleen Rey. Author. 61 |

    62 |
  • 63 |
64 |
65 |
66 |

Citation

67 | 68 |
69 |
70 | 71 | 72 |

Goode K, Rey K (2022). 73 | ggResidpanel: Panels and Interactive Versions of Diagnostic Plots using 'ggplot2'. 74 | R package version 0.3.0.9000, https://goodekat.github.io/ggResidpanel/. 75 |

76 |
@Manual{,
 77 |   title = {ggResidpanel: Panels and Interactive Versions of Diagnostic Plots using 'ggplot2'},
 78 |   author = {Katherine Goode and Kathleen Rey},
 79 |   year = {2022},
 80 |   note = {R package version 0.3.0.9000},
 81 |   url = {https://goodekat.github.io/ggResidpanel/},
 82 | }
83 | 84 |
85 | 86 |
87 | 88 | 89 | 90 |
93 | 94 |
95 |

Site built with pkgdown 2.0.1.

96 |
97 | 98 |
99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/favicon-16x16.png -------------------------------------------------------------------------------- /docs/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/favicon-32x32.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/favicon.ico -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/logo.png -------------------------------------------------------------------------------- /docs/news/index.html: -------------------------------------------------------------------------------- 1 | 2 | Changelog • ggResidpanel 6 | 7 | 8 |
    9 |
    44 | 45 | 46 | 47 |
    48 |
    49 | 53 | 54 |
    55 | 56 |
    57 |

    Major:

    58 |
    • changed resid_interact to allow for a panel of interactive plots
    • 59 |
    • added the functions of resid_xpanel and resid_compare
    • 60 |
    • added model types of lmerTest and lme
    • 61 |
    • added an introductory vignette
    • 62 |
    63 |
    64 |

    Minor:

    65 |
    • updated documentation
    • 66 |
    • added Cook’s distance values to residual-leverage plot
    • 67 |
    • reordered plots in “all” panels
    • 68 |
    • included penguins data
    • 69 |
    • rounded number in tool tip in resid_interact
    • 70 |
    • fixed some bugs in the code
    • 71 |
    72 |
    73 |
    74 | 75 |
    • first versions of ggResidpanel (the progression was not documented)
    • 76 |
    • introduced the functions of resid_panel, resid_interact, and resid_auxpanel
    • 77 |
    • allowed options in the functions for formatting options
    • 78 |
    79 |
    80 | 81 | 84 | 85 |
    86 | 87 | 88 |
    91 | 92 |
    93 |

    Site built with pkgdown 2.0.1.

    94 |
    95 | 96 |
    97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body { 21 | position: relative; 22 | } 23 | 24 | body > .container { 25 | display: flex; 26 | height: 100%; 27 | flex-direction: column; 28 | } 29 | 30 | body > .container .row { 31 | flex: 1 0 auto; 32 | } 33 | 34 | footer { 35 | margin-top: 45px; 36 | padding: 35px 0 36px; 37 | border-top: 1px solid #e5e5e5; 38 | color: #666; 39 | display: flex; 40 | flex-shrink: 0; 41 | } 42 | footer p { 43 | margin-bottom: 0; 44 | } 45 | footer div { 46 | flex: 1; 47 | } 48 | footer .pkgdown { 49 | text-align: right; 50 | } 51 | footer p { 52 | margin-bottom: 0; 53 | } 54 | 55 | img.icon { 56 | float: right; 57 | } 58 | 59 | /* Ensure in-page images don't run outside their container */ 60 | .contents img { 61 | max-width: 100%; 62 | height: auto; 63 | } 64 | 65 | /* Fix bug in bootstrap (only seen in firefox) */ 66 | summary { 67 | display: list-item; 68 | } 69 | 70 | /* Typographic tweaking ---------------------------------*/ 71 | 72 | .contents .page-header { 73 | margin-top: calc(-60px + 1em); 74 | } 75 | 76 | dd { 77 | margin-left: 3em; 78 | } 79 | 80 | /* Section anchors ---------------------------------*/ 81 | 82 | a.anchor { 83 | display: none; 84 | margin-left: 5px; 85 | width: 20px; 86 | height: 20px; 87 | 88 | background-image: url(./link.svg); 89 | background-repeat: no-repeat; 90 | background-size: 20px 20px; 91 | background-position: center center; 92 | } 93 | 94 | h1:hover .anchor, 95 | h2:hover .anchor, 96 | h3:hover .anchor, 97 | h4:hover .anchor, 98 | h5:hover .anchor, 99 | h6:hover .anchor { 100 | display: inline-block; 101 | } 102 | 103 | /* Fixes for fixed navbar --------------------------*/ 104 | 105 | .contents h1, .contents h2, .contents h3, .contents h4 { 106 | padding-top: 60px; 107 | margin-top: -40px; 108 | } 109 | 110 | /* Navbar submenu --------------------------*/ 111 | 112 | .dropdown-submenu { 113 | position: relative; 114 | } 115 | 116 | .dropdown-submenu>.dropdown-menu { 117 | top: 0; 118 | left: 100%; 119 | margin-top: -6px; 120 | margin-left: -1px; 121 | border-radius: 0 6px 6px 6px; 122 | } 123 | 124 | .dropdown-submenu:hover>.dropdown-menu { 125 | display: block; 126 | } 127 | 128 | .dropdown-submenu>a:after { 129 | display: block; 130 | content: " "; 131 | float: right; 132 | width: 0; 133 | height: 0; 134 | border-color: transparent; 135 | border-style: solid; 136 | border-width: 5px 0 5px 5px; 137 | border-left-color: #cccccc; 138 | margin-top: 5px; 139 | margin-right: -10px; 140 | } 141 | 142 | .dropdown-submenu:hover>a:after { 143 | border-left-color: #ffffff; 144 | } 145 | 146 | .dropdown-submenu.pull-left { 147 | float: none; 148 | } 149 | 150 | .dropdown-submenu.pull-left>.dropdown-menu { 151 | left: -100%; 152 | margin-left: 10px; 153 | border-radius: 6px 0 6px 6px; 154 | } 155 | 156 | /* Sidebar --------------------------*/ 157 | 158 | #pkgdown-sidebar { 159 | margin-top: 30px; 160 | position: -webkit-sticky; 161 | position: sticky; 162 | top: 70px; 163 | } 164 | 165 | #pkgdown-sidebar h2 { 166 | font-size: 1.5em; 167 | margin-top: 1em; 168 | } 169 | 170 | #pkgdown-sidebar h2:first-child { 171 | margin-top: 0; 172 | } 173 | 174 | #pkgdown-sidebar .list-unstyled li { 175 | margin-bottom: 0.5em; 176 | } 177 | 178 | /* bootstrap-toc tweaks ------------------------------------------------------*/ 179 | 180 | /* All levels of nav */ 181 | 182 | nav[data-toggle='toc'] .nav > li > a { 183 | padding: 4px 20px 4px 6px; 184 | font-size: 1.5rem; 185 | font-weight: 400; 186 | color: inherit; 187 | } 188 | 189 | nav[data-toggle='toc'] .nav > li > a:hover, 190 | nav[data-toggle='toc'] .nav > li > a:focus { 191 | padding-left: 5px; 192 | color: inherit; 193 | border-left: 1px solid #878787; 194 | } 195 | 196 | nav[data-toggle='toc'] .nav > .active > a, 197 | nav[data-toggle='toc'] .nav > .active:hover > a, 198 | nav[data-toggle='toc'] .nav > .active:focus > a { 199 | padding-left: 5px; 200 | font-size: 1.5rem; 201 | font-weight: 400; 202 | color: inherit; 203 | border-left: 2px solid #878787; 204 | } 205 | 206 | /* Nav: second level (shown on .active) */ 207 | 208 | nav[data-toggle='toc'] .nav .nav { 209 | display: none; /* Hide by default, but at >768px, show it */ 210 | padding-bottom: 10px; 211 | } 212 | 213 | nav[data-toggle='toc'] .nav .nav > li > a { 214 | padding-left: 16px; 215 | font-size: 1.35rem; 216 | } 217 | 218 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 219 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 220 | padding-left: 15px; 221 | } 222 | 223 | nav[data-toggle='toc'] .nav .nav > .active > a, 224 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 225 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 226 | padding-left: 15px; 227 | font-weight: 500; 228 | font-size: 1.35rem; 229 | } 230 | 231 | /* orcid ------------------------------------------------------------------- */ 232 | 233 | .orcid { 234 | font-size: 16px; 235 | color: #A6CE39; 236 | /* margins are required by official ORCID trademark and display guidelines */ 237 | margin-left:4px; 238 | margin-right:4px; 239 | vertical-align: middle; 240 | } 241 | 242 | /* Reference index & topics ----------------------------------------------- */ 243 | 244 | .ref-index th {font-weight: normal;} 245 | 246 | .ref-index td {vertical-align: top; min-width: 100px} 247 | .ref-index .icon {width: 40px;} 248 | .ref-index .alias {width: 40%;} 249 | .ref-index-icons .alias {width: calc(40% - 40px);} 250 | .ref-index .title {width: 60%;} 251 | 252 | .ref-arguments th {text-align: right; padding-right: 10px;} 253 | .ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} 254 | .ref-arguments .name {width: 20%;} 255 | .ref-arguments .desc {width: 80%;} 256 | 257 | /* Nice scrolling for wide elements --------------------------------------- */ 258 | 259 | table { 260 | display: block; 261 | overflow: auto; 262 | } 263 | 264 | /* Syntax highlighting ---------------------------------------------------- */ 265 | 266 | pre, code, pre code { 267 | background-color: #f8f8f8; 268 | color: #333; 269 | } 270 | pre, pre code { 271 | white-space: pre-wrap; 272 | word-break: break-all; 273 | overflow-wrap: break-word; 274 | } 275 | 276 | pre { 277 | border: 1px solid #eee; 278 | } 279 | 280 | pre .img, pre .r-plt { 281 | margin: 5px 0; 282 | } 283 | 284 | pre .img img, pre .r-plt img { 285 | background-color: #fff; 286 | } 287 | 288 | code a, pre a { 289 | color: #375f84; 290 | } 291 | 292 | a.sourceLine:hover { 293 | text-decoration: none; 294 | } 295 | 296 | .fl {color: #1514b5;} 297 | .fu {color: #000000;} /* function */ 298 | .ch,.st {color: #036a07;} /* string */ 299 | .kw {color: #264D66;} /* keyword */ 300 | .co {color: #888888;} /* comment */ 301 | 302 | .error {font-weight: bolder;} 303 | .warning {font-weight: bolder;} 304 | 305 | /* Clipboard --------------------------*/ 306 | 307 | .hasCopyButton { 308 | position: relative; 309 | } 310 | 311 | .btn-copy-ex { 312 | position: absolute; 313 | right: 0; 314 | top: 0; 315 | visibility: hidden; 316 | } 317 | 318 | .hasCopyButton:hover button.btn-copy-ex { 319 | visibility: visible; 320 | } 321 | 322 | /* headroom.js ------------------------ */ 323 | 324 | .headroom { 325 | will-change: transform; 326 | transition: transform 200ms linear; 327 | } 328 | .headroom--pinned { 329 | transform: translateY(0%); 330 | } 331 | .headroom--unpinned { 332 | transform: translateY(-100%); 333 | } 334 | 335 | /* mark.js ----------------------------*/ 336 | 337 | mark { 338 | background-color: rgba(255, 255, 51, 0.5); 339 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 340 | padding: 1px; 341 | } 342 | 343 | /* vertical spacing after htmlwidgets */ 344 | .html-widget { 345 | margin-bottom: 10px; 346 | } 347 | 348 | /* fontawesome ------------------------ */ 349 | 350 | .fab { 351 | font-family: "Font Awesome 5 Brands" !important; 352 | } 353 | 354 | /* don't display links in code chunks when printing */ 355 | /* source: https://stackoverflow.com/a/10781533 */ 356 | @media print { 357 | code a:link:after, code a:visited:after { 358 | content: ""; 359 | } 360 | } 361 | 362 | /* Section anchors --------------------------------- 363 | Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 364 | */ 365 | 366 | div.csl-bib-body { } 367 | div.csl-entry { 368 | clear: both; 369 | } 370 | .hanging-indent div.csl-entry { 371 | margin-left:2em; 372 | text-indent:-2em; 373 | } 374 | div.csl-left-margin { 375 | min-width:2em; 376 | float:left; 377 | } 378 | div.csl-right-inline { 379 | margin-left:2em; 380 | padding-left:1em; 381 | } 382 | div.csl-indent { 383 | margin-left: 2em; 384 | } 385 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $("div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.11.4 2 | pkgdown: 2.0.1 3 | pkgdown_sha: ~ 4 | articles: 5 | introduction: introduction.html 6 | last_built: 2022-01-02T00:03Z 7 | 8 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/Rplot002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/Rplot002.png -------------------------------------------------------------------------------- /docs/reference/Rplot003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/Rplot003.png -------------------------------------------------------------------------------- /docs/reference/Rplot004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/Rplot004.png -------------------------------------------------------------------------------- /docs/reference/figures/README/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/README/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README/unnamed-chunk-4-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/README/unnamed-chunk-4-2.png -------------------------------------------------------------------------------- /docs/reference/figures/README/unnamed-chunk-4-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/README/unnamed-chunk-4-3.png -------------------------------------------------------------------------------- /docs/reference/figures/README/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/README/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README/unnamed-chunk-6-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/README/unnamed-chunk-6-2.png -------------------------------------------------------------------------------- /docs/reference/figures/README/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/README/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/README/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/reference/figures/interact.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/interact.gif -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/reference/figures/readme-unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/readme-unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/reference/figures/readme-unnamed-chunk-4-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/readme-unnamed-chunk-4-2.png -------------------------------------------------------------------------------- /docs/reference/figures/readme-unnamed-chunk-4-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/readme-unnamed-chunk-4-3.png -------------------------------------------------------------------------------- /docs/reference/figures/readme-unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/readme-unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/reference/figures/readme-unnamed-chunk-6-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/readme-unnamed-chunk-6-2.png -------------------------------------------------------------------------------- /docs/reference/figures/readme-unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/readme-unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/reference/figures/readme-unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/readme-unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/reference/figures/static/interact.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/static/interact.gif -------------------------------------------------------------------------------- /docs/reference/figures/static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/figures/static/logo.png -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | Function reference • ggResidpanel 6 | 7 | 8 |
    9 |
    44 | 45 | 46 | 47 |
    48 |
    49 | 52 | 53 | 57 | 60 | 61 | 64 | 65 | 68 | 69 | 72 | 73 | 76 | 77 | 80 | 81 |
    54 |

    All functions

    55 |

    56 |
    58 |

    penguins

    59 |

    Penguins Dataset

    62 |

    resid_auxpanel()

    63 |

    Panel of Diagnostic Residual Plots.

    66 |

    resid_compare()

    67 |

    Panel of Diagnostic Residual Plots Across Multiple Models.

    70 |

    resid_interact()

    71 |

    Panel of Interactive Versions of Diagnostic Residual Plots.

    74 |

    resid_panel()

    75 |

    Panel of Diagnostic Residual Plots.

    78 |

    resid_xpanel()

    79 |

    Panel of Plots of Residuals or Response Variable versus Predictor Variables.

    82 | 83 | 86 |
    87 | 88 | 89 |
    92 | 93 |
    94 |

    Site built with pkgdown 2.0.1.

    95 |
    96 | 97 |
    98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /docs/reference/libs/crosstalk-1.1.1/css/crosstalk.css: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/reference/libs/plotly-htmlwidgets-css-1.57.1/plotly-htmlwidgets.css: -------------------------------------------------------------------------------- 1 | /* 2 | just here so that plotly works 3 | correctly with ioslides. 4 | see https://github.com/ropensci/plotly/issues/463 5 | */ 6 | 7 | slide:not(.current) .plotly.html-widget{ 8 | display: none; 9 | } 10 | -------------------------------------------------------------------------------- /docs/reference/penguins.html: -------------------------------------------------------------------------------- 1 | 2 | Penguins Dataset — penguins • ggResidpanel 11 | 12 | 13 |
    14 |
    49 | 50 | 51 | 52 |
    53 |
    54 | 59 | 60 |
    61 |

    A dataset that contains information from a study done on dives of emperor penguins by 62 | Jessica Meir and others. The scientists were interested in understanding how the heart 63 | rate of the penguins relates to the depth and duration of the dive. The study involved 64 | attaching a device to penguins that recorded the heart rate of the bird during a dive. 65 | The dataset contains multiple observations recorded from 9 penguins. The dataset has 66 | 125 observations and 4 variables.

    67 |
    68 | 69 |
    70 |
    penguins
    71 |
    72 | 73 |
    74 |

    Format

    75 |

    A data.frame.

    76 |
    77 | 81 |
    82 |

    Details

    83 |

    The variables in the dataset are as follows.

    heartrateHeart rate of the penguin during the dive (beats per minute)
    depthDepth of the dive (meters)
    durationDuration of the dive (minutes)
    birdThe id number associated with a penguin
    84 | 85 |
    86 | 89 |
    90 | 91 | 92 |
    95 | 96 |
    97 |

    Site built with pkgdown 2.0.1.

    98 |
    99 | 100 |
    101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/reference/resid_auxpanel-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_auxpanel-1.png -------------------------------------------------------------------------------- /docs/reference/resid_compare-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_compare-1.png -------------------------------------------------------------------------------- /docs/reference/resid_compare-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_compare-2.png -------------------------------------------------------------------------------- /docs/reference/resid_panel-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_panel-1.png -------------------------------------------------------------------------------- /docs/reference/resid_panel-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_panel-2.png -------------------------------------------------------------------------------- /docs/reference/resid_panel-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_panel-3.png -------------------------------------------------------------------------------- /docs/reference/resid_panel-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_panel-4.png -------------------------------------------------------------------------------- /docs/reference/resid_xpanel-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_xpanel-1.png -------------------------------------------------------------------------------- /docs/reference/resid_xpanel-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/docs/reference/resid_xpanel-2.png -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /404.html 5 | 6 | 7 | /LICENSE-text.html 8 | 9 | 10 | /articles/index.html 11 | 12 | 13 | /articles/introduction.html 14 | 15 | 16 | /authors.html 17 | 18 | 19 | /index.html 20 | 21 | 22 | /news/index.html 23 | 24 | 25 | /reference/index.html 26 | 27 | 28 | /reference/penguins.html 29 | 30 | 31 | /reference/resid_auxpanel.html 32 | 33 | 34 | /reference/resid_compare.html 35 | 36 | 37 | /reference/resid_interact.html 38 | 39 | 40 | /reference/resid_panel.html 41 | 42 | 43 | /reference/resid_xpanel.html 44 | 45 | 46 | -------------------------------------------------------------------------------- /inst/cleaning_penguins_data.R: -------------------------------------------------------------------------------- 1 | # Code for cleaning the penguin data 2 | # Data downloaded from https://dasl.datadescription.com/datafile/penguins/?_sfm_methods=Regression&_sfm_cases=4+59943&sf_paged=9 3 | 4 | # Information from webpage where the data is from: 5 | # Source: Jessica Meir personal communication 6 | # Number of Cases: 125 7 | # Story: 8 | # Emperor penguins are the most accomplished divers among birds, making routine 9 | # dives of 5–12 minutes, with the longest recorded dive over 27 minutes. These 10 | # birds can also dive to depths of over 500 meters! Since air-breathing animals like 11 | # penguins must hold their breath while submerged, the duration of any given dive 12 | # depends on how much oxygen is in the bird’s body at the beginning of the dive, how 13 | # quickly that oxygen gets used, and the lowest level of oxygen the bird can tolerate. 14 | # The rate of oxygen depletion is primarily determined by the penguin’s heart rate. 15 | # Consequently, studies of heart rates during dives can help us understand how these 16 | # animals regulate their oxygen consumption in order to make such impressive dives.The researchers equipped emperor penguins with devices that record their heart rates during 17 | # dives. The dataset reports Dive Heart Rate (beats per minute), the Duration 18 | # (minutes) of dives, and other related variables. 19 | 20 | # Load libraries 21 | library(dplyr) 22 | 23 | # Read in the penguin data 24 | penguins_raw <- read.delim("./data-raw/penguins.txt") 25 | 26 | # Clean the penguin data 27 | penguins <- penguins_raw %>% 28 | rename(heartrate = Dive.Heart.Rate, 29 | depth = Depth.m., 30 | duration = Duration.min., 31 | bird = Bird.) %>% 32 | mutate(bird = as.factor(as.numeric(bird))) %>% 33 | arrange(bird) 34 | 35 | # Add the cleaned penguins data to the data folder 36 | devtools::use_data(penguins, overwrite = TRUE) 37 | 38 | -------------------------------------------------------------------------------- /inst/figures/interact.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/interact.gif -------------------------------------------------------------------------------- /inst/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/logo.png -------------------------------------------------------------------------------- /inst/figures/readme-unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/readme-unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /inst/figures/readme-unnamed-chunk-4-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/readme-unnamed-chunk-4-2.png -------------------------------------------------------------------------------- /inst/figures/readme-unnamed-chunk-4-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/readme-unnamed-chunk-4-3.png -------------------------------------------------------------------------------- /inst/figures/readme-unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/readme-unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /inst/figures/readme-unnamed-chunk-6-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/readme-unnamed-chunk-6-2.png -------------------------------------------------------------------------------- /inst/figures/readme-unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/readme-unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /inst/figures/readme-unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/inst/figures/readme-unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /inst/ideas-for-future-work.md: -------------------------------------------------------------------------------- 1 | # To Do List 2 | 3 | ## Current 4 | 5 | - Write up list of questions 6 | - Work through Mark's examples 7 | - Check in with Mark 8 | - Clean up old to do list 9 | - Ask Katie about changing her email address 10 | - Work through list of issues on GitLab 11 | 12 | ## Old List 13 | 14 | Katie's Tasks: 15 | - Work on residual vignette (IN PROGRESS) 16 | - include a link to the residual document in the documentation 17 | - modify so works for predictive models (Research at least)(NOT FOR CRAN) 18 | -randomForest (from randomForest): contains 'y' and 'predicted' (class is randomForest.formula)( 19 | - neuralnet (from neuralnet): contains 'response', 'covariates' and 'data' (class is nn) 20 | - nnet (from nnet): contains 'residuals' and 'fitted.values' (class is nnet) 21 | - svm (from e1071): contains 'fitted' and 'residuals' (class is svm) 22 | - test file using testthat 23 | - how to add lmertest to testthat, but still test lmer as well ??? 24 | - Added in section for warnings and errors, tested all formatting options with 2 plots 25 | - NOTE:USING THE WORD plot instead of plots 26 | - NOTE: if plotting a panel of four plots, nrow DOES NOT USE THIRD ROW when nrow = 3 27 | - round all values shown in interactive plots 28 | - Check resid and predicted 29 | 30 | - Completed: 31 | - Rounded data tooltip to 2 decimal places if a decimal is present in any of the numbers and the variable is numeric 32 | - Added in a check so only rounds if has integers preceding the decimal to avoid roundin 0.0023 to 0 33 | - add code used to create sticker under data raw (code currently not working) 34 | - shorten title of constant leverage plot 35 | 36 | - fix resid_interact for binomial case to be more general (Double check names with Katherine) 37 | - make smoother tooltips consistent (Do we want observation added for smoother?) 38 | - proof read introduction: 39 | + menion that is not on CRAN yet, will need to change soon 40 | + leave Github installatin instructions, but mention to check github for working version? 41 | 42 | 43 | Katherine's Tasks 44 | - current: 45 | 46 | - later: 47 | - cleaning board game data and coach salary data to use for paper 48 | (and vignettes?) 49 | - add in links in vignettes to the residual vignette (when finished) 50 | - contact Jessica Meir to ask for citation of penguin data 51 | - figure out how to use the "safely" and "quietly" functions to only show 52 | desired warnings and suppress the error: 53 | grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : 54 | polygon edge not found 55 | 56 | 57 | Ideas for Future Package Versions: 58 | - write a function for computing standardized residuals for lmer and glmer (Katie) 59 | - look into testthat and vistest packages for testing 60 | - create an option for the user to add their own theme 61 | - add in minimum package versions?? (under imports) 62 | - add interactive versions of the auxpanel, xpanel, and compare plots 63 | - maybe add an option in each of the functions for an interactive version 64 | - option to color residuals by predictor variables? 65 | - add a resid versus y plot 66 | - read about mixed model influence diagnostics in SAS for mixed models (Stroup 2018) 67 | - nested residuals/plots for assessing random effects 68 | -------------------------------------------------------------------------------- /inst/penguins.txt: -------------------------------------------------------------------------------- 1 | Dive Heart Rate Depth(m) Duration(min) Bird# 2 | 88.8 5 1.05 EP19 3 | 103.4 9 1.1833333 EP19 4 | 97.4 22 1.9166667 EP19 5 | 85.3 25.5 3.4666667 EP19 6 | 60.6 30.5 7.0833333 EP19 7 | 77.6 32.5 4.7666667 EP19 8 | 44.3 38 9.1333333 EP19 9 | 32.8 32 11 EP19 10 | 94.2 6 1.3166667 EP19 11 | 99.8 10.5 1.4833333 EP19 12 | 104.5 6 1.1666667 EP19 13 | 78 19.5 2.7166667 EP19 14 | 54.2 27.5 7.25 EP19 15 | 79 33.5 4.7833333 EP19 16 | 42.9 40.5 11.866667 EP19 17 | 134 12 1.0833333 EP19 18 | 54.1 43 8.0166667 EP19 19 | 31.8 45.5 11.283333 EP19 20 | 49.4 35 8.1333333 EP19 21 | 57.1 33.5 6.0833333 EP19 22 | 50.2 147 9.0166667 EP22 23 | 97.3 66.5 2.3166667 EP22 24 | 32.3 116 10.866667 EP22 25 | 42.1 40 6.05 EP22 26 | 40.2 46.5 9.8333333 EP22 27 | 34.6 37 8.7666667 EP22 28 | 81 11 2 EP22 29 | 44.5 20.5 6.3666667 EP22 30 | 106.3 30.5 2.0666667 EP22 31 | 36.3 45 9.9333333 EP22 32 | 87.7 26 2.1166667 EP22 33 | 24.1 66 18.15 EP22 34 | 47.8 170 10.033333 EP43(2001) 35 | 44.9 160 9.9833333 EP43(2001) 36 | 45.5 140 10.5 EP43(2001) 37 | 47.7 40 5.2833333 EP43(2001) 38 | 49.1 25 5.1333333 EP43(2001) 39 | 43.6 49 7.3 EP43(2001) 40 | 68.1 100 3.35 EP43(2001) 41 | 51.7 52 5.9333333 EP43(2001) 42 | 91.1 39 2.8333333 EP43(2001) 43 | 34 47 9.0333333 EP43(2001) 44 | 52 39 4.7333333 EP43(2001) 45 | 103.8 26 1.9166667 EP43(2001) 46 | 34.8 42 7.0166667 EP43(2001) 47 | 36.9 90 9.2166667 EP43(2001) 48 | 48.6 160 7.4666667 EP43(2001) 49 | 43.8 160 8 EP43(2001) 50 | 52.5 130 6.9333333 EP43(2001) 51 | 67.2 32.32 3.7333333 EP32(05) 52 | 48.2 29.78 5.75 EP32(05) 53 | 52.3 66.94 8.1 EP32(05) 54 | 40.1 34.37 10.133317 EP32(05) 55 | 83.6 35.11 2.5833167 EP32(05) 56 | 55.4 49.22 6.2499667 EP32(05) 57 | 47.1 36.42 8.6333 EP32(05) 58 | 48.3 51.41 10.84995 EP32(05) 59 | 104.5 19.24 1.1 EP32(05) 60 | 54.9 37.4 8.8332833 EP32(05) 61 | 41 30.56 11.749933 EP32(05) 62 | 71.5 35.94 4.8499833 EP32(05) 63 | 74.7 33.35 3.6833167 EP32(05) 64 | 37.7 46.48 14.48325 EP32(05) 65 | 67.8 31.69 4.7333 EP32(05) 66 | 41.1 56.1 12.6166 EP32(05) 67 | 29.6 53.56 15.449917 EP32(05) 68 | 70.5 12.3 1.05 EP39(05) 69 | 47.1 25.88 5.36665 EP39(05) 70 | 34.1 36.33 8.9666167 EP39(05) 71 | 43.3 34.71 8.49995 EP39(05) 72 | 35.8 66.45 9.7999333 EP39(05) 73 | 32.7 43.8 10.933283 EP39(05) 74 | 40.3 50.49 10.5166 EP39(05) 75 | 36.2 44.43 10.483267 EP39(05) 76 | 84.4 31 2.25 EP39(05) 77 | 31.3 37.99 11.8166 EP39(05) 78 | 31.3 57.32 12.249933 EP39(05) 79 | 78.5 29.88 1.4643667 EP39(05) 80 | 31.5 44.63 9.2087 EP39(05) 81 | 57.5 20.41 2.41665 EP31(05) 82 | 67.8 22.41 1.9333167 EP31(05) 83 | 48.5 35.4 3.2999833 EP31(05) 84 | 33.7 74.51 10.799933 EP31(05) 85 | 27.5 57.76 13.5166 EP31(05) 86 | 29.9 53.9 11.949933 EP31(05) 87 | 39.2 75.97 9.4999333 EP31(05) 88 | 32.1 55.03 10.833267 EP31(05) 89 | 30.3 45.26 14.149933 EP31(05) 90 | 81.3 47.9 1.96665 EP31(05) 91 | 113.6 10.89 1.1 EP35(05) 92 | 80.9 16.94 1.4333167 EP35(05) 93 | 76.6 22.17 2.5333167 EP35(05) 94 | 39.5 47.12 7.1166333 EP35(05) 95 | 38.8 63.82 8.4999667 EP35(05) 96 | 22.8 53.61 12.583267 EP35(05) 97 | 34.3 59.91 10.683267 EP35(05) 98 | 121.7 22.61 1.1499833 EP35(05) 99 | 35.5 43.99 9.1166167 EP35(05) 100 | 36.3 49.51 9.8166 EP35(05) 101 | 25.5 46.19 11.983267 EP35(05) 102 | 33 40.87 8.99995 EP35(05) 103 | 111.2 31.64 1.8166667 EP35(05) 104 | 30.6 52.49 11.149933 EP35(05) 105 | 119.5 38.69 1.8499833 EP35(05) 106 | 28.1 56.15 14.68325 EP35(05) 107 | 73.3 22.75 2.1833333 EP36(05) 108 | 39 34.37 5.8166333 EP36(05) 109 | 28.5 45.65 9.89995 EP36(05) 110 | 24.2 46.43 10.3666 EP36(05) 111 | 23.5 54.49 12.399933 EP36(05) 112 | 25.3 67.38 11.5666 EP36(05) 113 | 46.6 37 8.3333333 EP39(01) 114 | 77.1 135 7.0666667 EP39(01) 115 | 77.5 225 7.4666667 EP39(01) 116 | 71.6 225 8.6166667 EP39(01) 117 | 101.8 28 2.8666667 EP39(01) 118 | 46.8 145 11.816667 EP39(01) 119 | 50.6 175 10.783333 EP39(01) 120 | 127.8 8.6 1.5333333 EP39(01) 121 | 42.1 165 13.533333 EP39(01) 122 | 48.4 170 11.533333 EP39(01) 123 | 50.8 37 8.2166667 EP39(01) 124 | 49.6 160 11.3 EP39(01) 125 | 56.4 180 10.283333 EP39(01) 126 | 55.2 170 10.366667 EP39(01) -------------------------------------------------------------------------------- /man/penguins.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_penguins.R 3 | \docType{data} 4 | \name{penguins} 5 | \alias{penguins} 6 | \title{Penguins Dataset} 7 | \format{ 8 | A data.frame. 9 | } 10 | \source{ 11 | \url{https://dasl.datadescription.com/datafile/penguins/?_sfm_methods=Regression&_sfm_cases=4+59943&sf_paged=9} 12 | } 13 | \usage{ 14 | penguins 15 | } 16 | \description{ 17 | A dataset that contains information from a study done on dives of emperor penguins by 18 | Jessica Meir and others. The scientists were interested in understanding how the heart 19 | rate of the penguins relates to the depth and duration of the dive. The study involved 20 | attaching a device to penguins that recorded the heart rate of the bird during a dive. 21 | The dataset contains multiple observations recorded from 9 penguins. The dataset has 22 | 125 observations and 4 variables. 23 | } 24 | \details{ 25 | The variables in the dataset are as follows. 26 | \tabular{ll}{ 27 | \code{heartrate} \tab Heart rate of the penguin during the dive (beats per minute) \cr 28 | \code{depth} \tab Depth of the dive (meters) \cr 29 | \code{duration} \tab Duration of the dive (minutes) \cr 30 | \code{bird} \tab The id number associated with a penguin} 31 | } 32 | \keyword{datasets} 33 | -------------------------------------------------------------------------------- /man/resid_auxpanel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/resid_auxpanel.R 3 | \name{resid_auxpanel} 4 | \alias{resid_auxpanel} 5 | \title{Panel of Diagnostic Residual Plots.} 6 | \usage{ 7 | resid_auxpanel( 8 | residuals, 9 | predicted, 10 | plots = "default", 11 | bins = 30, 12 | smoother = FALSE, 13 | qqline = TRUE, 14 | qqbands = FALSE, 15 | scale = 1, 16 | theme = "bw", 17 | axis.text.size = 10, 18 | title.text.size = 12, 19 | title.opt = TRUE, 20 | nrow = NULL, 21 | alpha = 0.6 22 | ) 23 | } 24 | \arguments{ 25 | \item{residuals}{The residuals from the model.} 26 | 27 | \item{predicted}{The fitted values from the model.} 28 | 29 | \item{plots}{Plots chosen to include in the panel of plots. The default panel 30 | includes a residual plot, a normal quantile plot, an index plot, 31 | and a histogram of the residuals. (See details for the options available.)} 32 | 33 | \item{bins}{Number of bins for histogram of the residuals. Default is set to 30.} 34 | 35 | \item{smoother}{Indicates whether or not to include a smoother on the 36 | residual plot and/or index plot. Specify TRUE or FALSE. Default is set to FALSE.} 37 | 38 | \item{qqline}{Indicates whether to include a 1-1 line on the qq-plot. Specify 39 | TRUE or FALSE. Default is set to TRUE.} 40 | 41 | \item{qqbands}{Indicates whether to include confidence bands on the qq-plot. 42 | Specify TRUE or FALSE. Default is set to FALSE.} 43 | 44 | \item{scale}{Scales the size of the graphs in a panel. Takes values in (0,1].} 45 | 46 | \item{theme}{ggplot2 theme to be used. Options are \code{"bw"}, 47 | \code{"classic"}, and \code{"grey"} (or \code{"gray"}). Default is 48 | \code{"bw"}.} 49 | 50 | \item{axis.text.size}{Specifies the size of the text for the axis labels of 51 | all plots.} 52 | 53 | \item{title.text.size}{Specifies the size of the text for the titles of all 54 | plots.} 55 | 56 | \item{title.opt}{Indicates whether or not to include a title on the plots. 57 | Specify TRUE or FALSE. Default is set to TRUE.} 58 | 59 | \item{nrow}{Sets the number of rows in the panel.} 60 | 61 | \item{alpha}{Sets the alpha level for displays with points. Default is set to 0.6.} 62 | } 63 | \value{ 64 | A panel of residual diagnostic plots containing plots specified. 65 | } 66 | \description{ 67 | Creates a panel of residual diagnostic plots given inputs of residuals and 68 | fitted values. 69 | } 70 | \details{ 71 | The following grid options can be chosen for the \code{plots} 72 | argument. 73 | \itemize{ 74 | \item "all": This creates a panel of all plot types included in the package 75 | that are available for \code{resid_auxpanel}. (See plot descriptions under 76 | individual options.) 77 | \item "default": This creates a panel with a residual plot, a normal quantile plot 78 | of the residuals, an index plot of the residuals, and a histogram of the residuals. 79 | \item "SAS": This creates a panel of a residual plot, a normal quantile plot of the 80 | residuals, a histogram of the residuals, and a boxplot of the residuals. This was 81 | modeled after the residpanel option in proc mixed from SAS version 9.4. 82 | \item A vector of individual plots can also be specified. For example, one 83 | can specify \code{plots = c("boxplot", "hist")} or \code{plots = "qq"}. The 84 | individual plot options are as follows. 85 | \itemize{ 86 | \item \code{"boxplot"}: A boxplot of residuals 87 | \item \code{"hist"}: A histogram of residuals 88 | \item \code{"index"}: A plot of residuals versus observation number 89 | \item \code{"qq"}: A normal quantile plot of residuals 90 | \item \code{"resid"}: A plot of residuals versus predicted values 91 | } } 92 | 93 | Details on the creation of the plots can be found in the details section of 94 | the help file for \code{resid_panel}. 95 | } 96 | \examples{ 97 | 98 | # Fit a regression tree to the penguins data 99 | penguin_tree <- rpart::rpart(heartrate ~ depth + duration, data = penguins) 100 | 101 | # Obtain the predictions from the model on the observed data 102 | penguin_tree_pred <- predict(penguin_tree) 103 | 104 | # Obtain the residuals from the model 105 | penguin_tree_resid <- penguins$heartrate - penguin_tree_pred 106 | 107 | # Create a panel with the residual and index plot 108 | resid_auxpanel(residuals = penguin_tree_resid, 109 | predicted = penguin_tree_pred, 110 | plots = c("resid", "index", "yvp")) 111 | } 112 | -------------------------------------------------------------------------------- /man/resid_compare.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/resid_compare.R 3 | \name{resid_compare} 4 | \alias{resid_compare} 5 | \title{Panel of Diagnostic Residual Plots Across Multiple Models.} 6 | \usage{ 7 | resid_compare( 8 | models, 9 | plots = "default", 10 | type = NA, 11 | bins = 30, 12 | smoother = TRUE, 13 | qqline = TRUE, 14 | qqbands = FALSE, 15 | scale = 1, 16 | theme = "bw", 17 | axis.text.size = 10, 18 | title.text.size = 12, 19 | title.opt = TRUE, 20 | nrow = NULL, 21 | alpha = 0.6 22 | ) 23 | } 24 | \arguments{ 25 | \item{models}{List of models fit using either \code{lm}, \code{glm}, \code{lmer}, 26 | \code{lmerTest}, or \code{glmer}.} 27 | 28 | \item{plots}{Plots chosen to include in the panel of plots. The default panel 29 | includes a residual plot, a normal quantile plot, an index plot, 30 | and a histogram of the residuals. (See details for the options available.)} 31 | 32 | \item{type}{Type of residuals to use in the plot. If not specified, the 33 | default residual type for each model type is used. (See details for the 34 | options available.)} 35 | 36 | \item{bins}{Number of bins to use when creating a histogram of the residuals. 37 | Default is set to 30.} 38 | 39 | \item{smoother}{Indicates whether or not to include a smoother on the residual 40 | vs fitted and index plots. Specify TRUE or FALSE. Default is set to TRUE.} 41 | 42 | \item{qqline}{Indicates whether to include a 1-1 line on the qq-plot. Specify 43 | TRUE or FALSE. Default is set to TRUE.} 44 | 45 | \item{qqbands}{Indicates whether to include confidence bands on the qq-plot. 46 | Specify TRUE or FALSE. Default is set to FALSE.} 47 | 48 | \item{scale}{Scales the size of the graphs in the panel. Takes values in (0,1].} 49 | 50 | \item{theme}{ggplot2 theme to be used. Current options are \code{"bw"}, 51 | \code{"classic"}, and \code{"grey"} (or \code{"gray"}). Default is 52 | \code{"bw"}.} 53 | 54 | \item{axis.text.size}{Specifies the size of the text for the axis labels of 55 | all plots in the panel.} 56 | 57 | \item{title.text.size}{Specifies the size of the text for the titles of all 58 | plots in the panel.} 59 | 60 | \item{title.opt}{Indicates whether or not to include a title on the plots in 61 | the panel. Specify TRUE or FALSE. Default is set to TRUE.} 62 | 63 | \item{nrow}{Sets the number of rows in the panel.} 64 | 65 | \item{alpha}{Sets the alpha level for displays with points. Default is set to 0.6.} 66 | } 67 | \value{ 68 | A panel of residual diagnostic plots containing plots specified for each model. 69 | } 70 | \description{ 71 | Creates a panel of residual diagnostic plots given a list of models. Currently accepts 72 | models of type "lm", "glm", "lmerMod", "lmerModLmerTest", and "glmerMod". 73 | } 74 | \details{ 75 | The first two sections below contain information on the available input 76 | options for the \code{plots} and \code{type} arguments in \code{resid_compare}. 77 | The third section contains details relating to the creation of the plots. 78 | 79 | \strong{Options for Plots} 80 | 81 | The following options can be chosen for the \code{plots} argument. 82 | \itemize{ 83 | \item "all": This creates a panel of all plot types included in the package 84 | that are available for the model type input into \code{residpanel}. (See note 85 | below.) 86 | \item "default": This creates a panel with a residual plot, a normal quantile plot 87 | of the residuals, an index plot of the residuals, and a histogram of the residuals. 88 | \item "R": This creates a panel with a residual plot, a normal 89 | quantile plot of the residuals, a location-scale plot, and a leverage versus 90 | residuals plot. This was modeled after the plots shown in R if the 91 | \code{plot()} base function is applied to an \code{lm} model. This option can 92 | only be used with an \code{lm} or \code{glm} model. 93 | \item "SAS": This creates a panel with a residual plot, a normal quantile plot of 94 | the residuals, a histogram of the residuals, and a boxplot of the residuals. 95 | This was modeled after the residpanel option in proc mixed from SAS version 9.4. 96 | \item A vector of individual plots can also be specified. 97 | For example, one can specify \code{plots = c("boxplot", "hist")} or 98 | \code{plots = "qq"}. The individual plot options are as follows. 99 | \itemize{ 100 | \item \code{"boxplot"}: A boxplot of residuals 101 | \item \code{"cookd"}: A plot of Cook's D values versus observation numbers 102 | \item \code{"hist"}: A histogram of residuals 103 | \item \code{"index"}: A plot of residuals versus observation numbers 104 | \item \code{"ls"}: A location scale plot of the residuals 105 | \item \code{"qq"}: A normal quantile plot of residuals 106 | \item \code{"lev"}: A plot of leverage values versus residuals 107 | \item \code{"resid"}: A plot of residuals versus predicted values 108 | \item \code{"yvp":}: A plot of observed response values versus predicted values 109 | } } 110 | 111 | Note: \code{"cookd"}, \code{"ls"}, and \code{"lev"} are only available for "lm" 112 | and "glm" models. 113 | 114 | \strong{Options for Type} 115 | 116 | Several residual types are available to be requested based on the model type 117 | that is input into \code{resid_panel}. These currently are as follows. 118 | \itemize{ 119 | \item \code{lm} residual options 120 | \itemize{ 121 | \item \code{"pearson"}:The Pearson residuals 122 | \item \code{"response"}: The raw residuals (Default for "lm") 123 | \item \code{"standardized"}: The standardized raw residuals 124 | } 125 | \item \code{glm} residual options 126 | \itemize{ 127 | \item \code{"pearson"}: The Pearson residuals 128 | \item \code{"deviance"}: The deviance residuals (Default for "glm") 129 | \item \code{"response"}: The raw residuals 130 | \item \code{"stand.deviance"}: The standardized deviance residuals 131 | \item \code{"stand.pearson"}: The standardized Pearson residuals 132 | } 133 | \item \code{lmer}, \code{lmerTest}, and \code{lme} residual options 134 | \itemize{ 135 | \item \code{"pearson"}: The Pearson residuals (Default for "lmer", "lmerTest", and "lme") 136 | \item \code{"response"}: The raw residuals 137 | } 138 | \item \code{glmer} residual options 139 | \itemize{ 140 | \item \code{"pearson"}: The Pearson residuals 141 | \item \code{"deviance"}: The deviance residuals (Default for "glmer") 142 | \item \code{"response"}: The raw residuals 143 | } } 144 | 145 | Note: The plots of \code{"ls"} and \code{"lev"} only accept standardized residuals. 146 | 147 | \strong{Details on the Creation of Plots} 148 | 149 | \describe{ 150 | \item{Boxplot (\code{boxplot})}{Boxplot of the residuals.} 151 | 152 | \item{Cook's D (\code{cookd})}{ The horizontal line represents a cut-off to identify 153 | highly influential points. The horizontal line is placed at 4/n where n is 154 | the number of data points used in the \code{model}.} 155 | 156 | \item{Histogram (\code{hist})}{Plots a histogram of the residuals. The density 157 | curve overlaid has mean equal to zero and standard deviation equal to the 158 | standard deviation of the residuals.} 159 | 160 | \item{Index Plot (\code{index})}{Plots the residuals on the y-axis and the observation 161 | number associated with the residual on the x-axis.} 162 | 163 | \item{Leverage Plot (\code{lev})}{Plots the standardized residuals on the y-axis 164 | and the leverage values on the x-axis. A lowess curve is overlaid, and Cook's 165 | D contours are included for \eqn{\alpha = 0.5} and \eqn{\alpha = 1}.} 166 | 167 | \item{Location-Scale Plot (\code{ls})}{Plots the square root of the absolute value 168 | of the standardized residuals on the y-axis and the predicted values on the 169 | x-axis. The predicted values are plotted on the original scale for \code{glm} 170 | and \code{glmer} models. A lowess curve is overlaid.} 171 | 172 | \item{QQ Plot (\code{qq})}{Makes use of the \code{R} package \code{qqplotr} for 173 | creating a normal quantile plot of the residuals.} 174 | 175 | \item{Residual Plot (\code{resid})}{Plots the residuals on the y-axis and the 176 | predicted values on the x-axis. The predicted values are plotted on the 177 | original scale for \code{glm} and \code{glmer} models.} 178 | 179 | \item{Response vs. Predicted (\code{yvp})}{Plots the response variable from the 180 | model on the y-axis and the predicted values on the x-axis. Both response 181 | variable and predicted values are plotted on the original scale for 182 | \code{glm} and \code{glmer} models.} 183 | } 184 | } 185 | \examples{ 186 | 187 | # Fit two models to the penguins data 188 | penguin_model <- lme4::lmer(heartrate ~ depth + duration + (1|bird), data = penguins) 189 | penguin_model_log2 <- lme4::lmer(log(heartrate) ~ depth + duration + I(duration^2) + 190 | (1|bird), data = penguins) 191 | 192 | # Compare the residuals from the model 193 | resid_compare(list(penguin_model, penguin_model_log2)) 194 | 195 | # Adjust some options in the panel of plots 196 | resid_compare(list(penguin_model, penguin_model_log2), plots = c("resid", "yvp"), 197 | smoother = TRUE, theme = "grey") 198 | } 199 | -------------------------------------------------------------------------------- /man/resid_interact.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/resid_interact.R 3 | \name{resid_interact} 4 | \alias{resid_interact} 5 | \title{Panel of Interactive Versions of Diagnostic Residual Plots.} 6 | \usage{ 7 | resid_interact( 8 | model, 9 | plots = "default", 10 | type = NA, 11 | bins = 30, 12 | smoother = TRUE, 13 | qqline = TRUE, 14 | scale = 0.9, 15 | theme = "bw", 16 | axis.text.size = 10, 17 | title.text.size = 12, 18 | title.opt = TRUE, 19 | nrow = NULL, 20 | alpha = 0.6 21 | ) 22 | } 23 | \arguments{ 24 | \item{model}{Model fit using either \code{lm}, \code{glm}, \code{lmer}, 25 | \code{lmerTest}, \code{lme}, or \code{glmer}.} 26 | 27 | \item{plots}{Plots chosen to include in the panel of plots. The default panel 28 | includes a residual plot, a normal quantile plot, an index plot, 29 | and a histogram of the residuals. (See details in the help file 30 | for \code{resid_panel} for the options available.)} 31 | 32 | \item{type}{Type of residuals to use in the plot. If not specified, the 33 | default residual type for each model type is used. (See details in the help file 34 | for \code{resid_panel} for the options available.)} 35 | 36 | \item{bins}{Number of bins to use when creating a histogram of the residuals. 37 | Default is set to 30.} 38 | 39 | \item{smoother}{Indicates whether or not to include a smoother on the residual 40 | vs fitted and index plots. Specify TRUE or FALSE. Default is set to TRUE.} 41 | 42 | \item{qqline}{Indicates whether to include a 1-1 line on the qq-plot. Specify 43 | TRUE or FALSE. Default is set to TRUE. (The option of \code{qqbands} has not 44 | been implemented in plotly, so it is not available as an option with 45 | \code{resid_interact}.)} 46 | 47 | \item{scale}{Scales the size of the graphs in the panel. Takes values in (0,1].} 48 | 49 | \item{theme}{ggplot2 theme to be used. Current options are \code{"bw"}, 50 | \code{"classic"}, and \code{"grey"} (or \code{"gray"}). Default is 51 | \code{"bw"}.} 52 | 53 | \item{axis.text.size}{Specifies the size of the text for the axis labels of 54 | all plots in the panel.} 55 | 56 | \item{title.text.size}{Specifies the size of the text for the titles of all 57 | plots in the panel.} 58 | 59 | \item{title.opt}{Indicates whether or not to include a title on the plots in 60 | the panel. Specify TRUE or FALSE. Default is set to TRUE.} 61 | 62 | \item{nrow}{Sets the number of rows in the panel.} 63 | 64 | \item{alpha}{Sets the alpha level for displays with points. Default is set to 0.6.} 65 | } 66 | \value{ 67 | A panel of interactive residual diagnostic plots containing plots specified. 68 | } 69 | \description{ 70 | Creates a panel of interactive residual diagnostic plots given a model. Currently 71 | accepts models of type "lm", "glm", "lmerMod", "lmerModLmerTest", "lme", and "glmerMod". 72 | } 73 | \details{ 74 | Details on the creation of the plots can be found in the details section of 75 | the help file for \code{resid_panel}. 76 | } 77 | \examples{ 78 | 79 | # Fit a model to the penguin data 80 | penguin_model <- lme4::lmer(heartrate ~ depth + duration + (1|bird), data = penguins) 81 | 82 | # Create the default interactive panel 83 | resid_interact(penguin_model) 84 | 85 | # Select only the residual plot and qq-plot to be included in the panel, 86 | # set the number of rows to 2, change the theme to classic 87 | resid_interact(penguin_model, plots = c("resid", "qq"), nrow = 2, theme = "classic") 88 | } 89 | -------------------------------------------------------------------------------- /man/resid_panel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/resid_panel.R 3 | \name{resid_panel} 4 | \alias{resid_panel} 5 | \title{Panel of Diagnostic Residual Plots.} 6 | \usage{ 7 | resid_panel( 8 | model, 9 | plots = "default", 10 | type = NA, 11 | bins = 30, 12 | smoother = TRUE, 13 | qqline = TRUE, 14 | qqbands = FALSE, 15 | scale = 1, 16 | theme = "bw", 17 | axis.text.size = 10, 18 | title.text.size = 12, 19 | title.opt = TRUE, 20 | nrow = NULL, 21 | alpha = 0.6 22 | ) 23 | } 24 | \arguments{ 25 | \item{model}{Model fit using either \code{lm}, \code{glm}, \code{lmer}, 26 | \code{lmerTest}, \code{lme}, or \code{glmer}.} 27 | 28 | \item{plots}{Plots chosen to include in the panel of plots. The default panel 29 | includes a residual plot, a normal quantile plot, an index plot, 30 | and a histogram of the residuals. (See details for the options available.)} 31 | 32 | \item{type}{Type of residuals to use in the plot. If not specified, the 33 | default residual type for each model type is used. (See details for the 34 | options available.)} 35 | 36 | \item{bins}{Number of bins to use when creating a histogram of the residuals. 37 | Default is set to 30.} 38 | 39 | \item{smoother}{Indicates whether or not to include a smoother on the residual 40 | vs fitted and index plots. Specify TRUE or FALSE. Default is set to TRUE.} 41 | 42 | \item{qqline}{Indicates whether to include a 1-1 line on the qq-plot. Specify 43 | TRUE or FALSE. Default is set to TRUE.} 44 | 45 | \item{qqbands}{Indicates whether to include confidence bands on the qq-plot. 46 | Specify TRUE or FALSE. Default is set to FALSE.} 47 | 48 | \item{scale}{Scales the size of the graphs in the panel. Takes values in (0,1].} 49 | 50 | \item{theme}{ggplot2 theme to be used. Current options are \code{"bw"}, 51 | \code{"classic"}, and \code{"grey"} (or \code{"gray"}). Default is 52 | \code{"bw"}.} 53 | 54 | \item{axis.text.size}{Specifies the size of the text for the axis labels of 55 | all plots in the panel.} 56 | 57 | \item{title.text.size}{Specifies the size of the text for the titles of all 58 | plots in the panel.} 59 | 60 | \item{title.opt}{Indicates whether or not to include a title on the plots in 61 | the panel. Specify TRUE or FALSE. Default is set to TRUE.} 62 | 63 | \item{nrow}{Sets the number of rows in the panel.} 64 | 65 | \item{alpha}{Sets the alpha level for displays with points. Default is set to 0.6.} 66 | } 67 | \value{ 68 | A panel of residual diagnostic plots containing plots specified. 69 | } 70 | \description{ 71 | Creates a panel of residual diagnostic plots given a model. Currently accepts 72 | models of type "lm", "glm", "lmerMod", "lmerModLmerTest", "lme", and "glmerMod". 73 | } 74 | \details{ 75 | The first two sections below contain information on the available input 76 | options for the \code{plots} and \code{type} arguments in \code{resid_panel}. 77 | The third section contains details relating to the creation of the plots. 78 | 79 | \strong{Options for Plots} 80 | 81 | The following options can be chosen for the \code{plots} argument. 82 | \itemize{ 83 | \item "all": This creates a panel of all plot types included in the package 84 | that are available for the model type input into \code{resid_panel}. (See note 85 | below.) 86 | \item "default": This creates a panel with a residual plot, a normal quantile plot 87 | of the residuals, an index plot of the residuals, and a histogram of the residuals. 88 | \item "R": This creates a panel with a residual plot, a normal 89 | quantile plot of the residuals, a location-scale plot, and a residuals versus leverage 90 | plot. This was modeled after the plots shown in R if the \code{plot()} base function 91 | is applied to an \code{lm} model. This option can only be used with an \code{lm} or 92 | \code{glm} model. 93 | \item "SAS": This creates a panel with a residual plot, a normal quantile plot of 94 | the residuals, a histogram of the residuals, and a boxplot of the residuals. 95 | This was modeled after the residualpanel option in proc mixed from SAS version 9.4. 96 | \item A vector of individual plots can also be specified. 97 | For example, one can specify \code{plots = c("boxplot", "hist")} or 98 | \code{plots = "qq"}. The individual plot options are as follows. 99 | \itemize{ 100 | \item \code{"boxplot"}: A boxplot of residuals 101 | \item \code{"cookd"}: A plot of Cook's D values versus observation numbers 102 | \item \code{"hist"}: A histogram of residuals 103 | \item \code{"index"}: A plot of residuals versus observation numbers 104 | \item \code{"ls"}: A location scale plot of the residuals 105 | \item \code{"qq"}: A normal quantile plot of residuals 106 | \item \code{"lev"}: A plot of standardized residuals versus leverage values 107 | \item \code{"resid"}: A plot of residuals versus predicted values 108 | \item \code{"yvp":}: A plot of observed response values versus predicted values 109 | } } 110 | 111 | Note: \code{"cookd"}, \code{"ls"}, and \code{"lev"} are only available for "lm" and 112 | "glm" models. 113 | 114 | \strong{Options for Type} 115 | 116 | Several residual types are available to be requested based on the model type 117 | that is input into \code{resid_panel}. These currently are as follows. 118 | \itemize{ 119 | \item \code{lm} residual options 120 | \itemize{ 121 | \item \code{"pearson"}:The Pearson residuals 122 | \item \code{"response"}: The raw residuals (Default for "lm") 123 | \item \code{"standardized"}: The standardized raw residuals 124 | } 125 | \item \code{glm} residual options 126 | \itemize{ 127 | \item \code{"pearson"}: The Pearson residuals 128 | \item \code{"deviance"}: The deviance residuals (Default for "glm") 129 | \item \code{"response"}: The raw residuals 130 | \item \code{"stand.deviance"}: The standardized deviance residuals 131 | \item \code{"stand.pearson"}: The standardized Pearson residuals 132 | } 133 | \item \code{lmer}, \code{lmerTest}, and \code{lme} residual options 134 | \itemize{ 135 | \item \code{"pearson"}: The Pearson residuals (Default for "lmer", "lmerTest", and "lme") 136 | \item \code{"response"}: The raw residuals 137 | } 138 | \item \code{glmer} residual options 139 | \itemize{ 140 | \item \code{"pearson"}: The Pearson residuals 141 | \item \code{"deviance"}: The deviance residuals (Default for "glmer") 142 | \item \code{"response"}: The raw residuals 143 | } } 144 | 145 | Note: The plots of \code{"ls"} and \code{"lev"} only accept standardized residuals. 146 | 147 | \strong{Details on the Creation of Plots} 148 | 149 | \describe{ 150 | \item{Boxplot (\code{boxplot})}{Boxplot of the residuals.} 151 | 152 | \item{Cook's D (\code{cookd})}{ The horizontal line represents a cut-off to identify 153 | highly influential points. The horizontal line is placed at 4/n where n is 154 | the number of data points used in the \code{model}.} 155 | 156 | \item{Histogram (\code{hist})}{Plots a histogram of the residuals. The density 157 | curve overlaid has mean equal to zero and standard deviation equal to the 158 | standard deviation of the residuals.} 159 | 160 | \item{Index Plot (\code{index})}{Plots the residuals on the y-axis and the observation 161 | number associated with the residual on the x-axis.} 162 | 163 | \item{Residual-Leverage Plot (\code{lev})}{Plots the standardized residuals on the 164 | y-axis and the leverage values on the x-axis with a loess curve is overlaid. Cook's 165 | D contour lines (which are a function of leverage and standardized residuals) are plotted 166 | as the red dashed lines for Cook's D values of 0.5 and 1.} 167 | 168 | \item{Location-Scale Plot (\code{ls})}{Plots the square root of the absolute value 169 | of the standardized residuals on the y-axis and the predicted values on the 170 | x-axis. The predicted values are plotted on the original scale for \code{glm} 171 | and \code{glmer} models. A loess curve is overlaid.} 172 | 173 | \item{QQ Plot (\code{qq})}{Makes use of the \code{R} package \code{qqplotr} for 174 | creating a normal quantile plot of the residuals.} 175 | 176 | \item{Residual Plot (\code{resid})}{Plots the residuals on the y-axis and the 177 | predicted values on the x-axis. The predicted values are plotted on the 178 | original scale for \code{glm} and \code{glmer} models.} 179 | 180 | \item{Response vs. Predicted (\code{yvp})}{Plots the response variable from the 181 | model on the y-axis and the predicted values on the x-axis. Both response 182 | variable and predicted values are plotted on the original scale for 183 | \code{glm} and \code{glmer} models.} 184 | } 185 | } 186 | \examples{ 187 | 188 | # Fit a model to the penguin data 189 | penguin_model <- lme4::lmer(heartrate ~ depth + duration + (1|bird), data = penguins) 190 | 191 | # Create the default panel 192 | resid_panel(penguin_model) 193 | 194 | # Select all plots to include in the panel and set the smoother option to TRUE 195 | resid_panel(penguin_model, plots = "all", smoother = TRUE) 196 | 197 | # Select only the residual plot and qq-plot to be included in the panel, 198 | # request confidence bands on the qq plot, and set the number of rows to 2 199 | resid_panel(penguin_model, plots = c("resid", "qq"), qqbands = TRUE, nrow = 2) 200 | 201 | # Choose the SAS panel of plots, change the theme to classic, and remove the 202 | # titles of the plots 203 | resid_panel(penguin_model, plots = "SAS", theme = "classic", title.opt = FALSE) 204 | } 205 | -------------------------------------------------------------------------------- /man/resid_xpanel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/resid_xpanel.R 3 | \name{resid_xpanel} 4 | \alias{resid_xpanel} 5 | \title{Panel of Plots of Residuals or Response Variable versus Predictor Variables.} 6 | \usage{ 7 | resid_xpanel( 8 | model, 9 | yvar = "residual", 10 | type = NA, 11 | smoother = FALSE, 12 | scale = 1, 13 | theme = "bw", 14 | axis.text.size = 10, 15 | title.text.size = 12, 16 | title.opt = TRUE, 17 | nrow = NULL, 18 | jitter.width = 0, 19 | alpha = 0.6 20 | ) 21 | } 22 | \arguments{ 23 | \item{model}{Model fit using either \code{lm}, \code{glm}, \code{lmer}, 24 | \code{lmerTest}, \code{lme}, or \code{glmer}.} 25 | 26 | \item{yvar}{Specifies the variable to put on the y-axis of the plots. Options 27 | are "residual" (default) or "response".} 28 | 29 | \item{type}{Type of residuals to use in the plot. If not specified, the 30 | default residual type for each model type is used. (See details for the 31 | options available.)} 32 | 33 | \item{smoother}{Indicates whether or not to include a smoother on the 34 | plots. Specify TRUE or FALSE. Default is set to FALSE.} 35 | 36 | \item{scale}{Scales the size of the graphs in the panel. Takes values in (0,1].} 37 | 38 | \item{theme}{ggplot2 theme to be used. Current options are \code{"bw"}, 39 | \code{"classic"}, and \code{"grey"} (or \code{"gray"}). Default is 40 | \code{"bw"}.} 41 | 42 | \item{axis.text.size}{Specifies the size of the text for the axis labels of 43 | all plots in the panel.} 44 | 45 | \item{title.text.size}{Specifies the size of the text for the titles of all 46 | plots in the panel.} 47 | 48 | \item{title.opt}{Indicates whether or not to include a title on the plots in 49 | the panel. Specify TRUE or FALSE. Default is set to TRUE.} 50 | 51 | \item{nrow}{Sets the number of rows in the panel.} 52 | 53 | \item{jitter.width}{Specifies the amount of jitter to add in the plots of categorical variables. (Default is 0.)} 54 | 55 | \item{alpha}{Sets the alpha level for displays with points. Default is set to 0.6.} 56 | } 57 | \value{ 58 | A panel of plots of the residuals or response variable versus the 59 | predictor variables. Violin plots are included with categorical variables. 60 | } 61 | \description{ 62 | Creates a panel of plots of the residuals or response variable versus the 63 | predictor (x) variables in the model. Interactions between predictor variables 64 | are not included. Currently accepts models of type "lm", "glm", "lmerMod", 65 | "lmerModLmerTest", "lme", and "glmerMod". 66 | } 67 | \details{ 68 | Note that for x variables that are factors, the levels shown on the 69 | x-axis will be in the order that the levels are ordered in the dataframe. 70 | This can be adjusted by reordering the levels of the factor before the model 71 | is fit. 72 | } 73 | \examples{ 74 | 75 | # Fit a model to the penguin data 76 | penguin_model <- lme4::lmer(heartrate ~ depth + duration + (1|bird), data = penguins) 77 | 78 | # Create plots of the residuals versus the predictor variables 79 | resid_xpanel(penguin_model, theme = "classic", jitter.width = 0.1) 80 | 81 | # Create plots of the response variable versus the predictor variables 82 | resid_xpanel( 83 | model = penguin_model, 84 | yvar = "response", 85 | theme = "classic", 86 | smoother = TRUE, 87 | jitter.width = 0.1 88 | ) 89 | 90 | } 91 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goodekat/ggResidpanel/a23ade50e0473fc8a1e1b2e5ff2c4b9e3b95fb86/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # This file is part of the standard setup for testthat. 2 | # It is recommended that you do not modify it. 3 | # 4 | # Where should you do additional test configuration? 5 | # Learn more about the roles of various files in: 6 | # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview 7 | # * https://testthat.r-lib.org/articles/special-files.html 8 | 9 | library(testthat) 10 | library(ggResidpanel) 11 | 12 | test_check("ggResidpanel") 13 | --------------------------------------------------------------------------------