├── .Rbuildignore ├── .gitattributes ├── .github └── workflows │ └── rhub.yaml ├── .gitignore ├── .travis.yml ├── CONDUCT.md ├── CRAN-SUBMISSION ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── add_brackets.R ├── by_2sd.R ├── dwplot.R ├── globals.R ├── relabel_predictors.R ├── relabel_y_axis.R ├── secret_weapon.R └── small_multiple.R ├── README.md ├── cran-comments.md ├── dev ├── developing-note.qmd ├── jss │ ├── LICENSE │ ├── _extensions │ │ └── jss │ │ │ ├── _extension.yml │ │ │ ├── _extensions │ │ │ └── quarto-ext │ │ │ │ └── fancy-text │ │ │ │ ├── _extension.yml │ │ │ │ └── fancy-text.lua │ │ │ ├── jss.bst │ │ │ ├── jss.cls │ │ │ ├── jss.lua │ │ │ ├── jsslogo.jpg │ │ │ └── partials │ │ │ ├── _print-address.tex │ │ │ ├── _print-author.tex │ │ │ ├── before-body.tex │ │ │ └── title.tex │ ├── dotwhisker.bib │ ├── jss.bst │ ├── jss.cls │ ├── jss_dotwhisker.pdf │ ├── jss_dotwhisker.qmd │ └── jsslogo.jpg └── runBeforeRelease.R ├── docs ├── 404.html ├── CONDUCT.html ├── LICENSE-text.html ├── articles │ ├── dotwhisker-vignette.html │ ├── dotwhisker-vignette_files │ │ ├── figure-html │ │ │ ├── basic-1.png │ │ │ ├── brackets-1.png │ │ │ ├── by2sd-1.png │ │ │ ├── ci-1.png │ │ │ ├── clm-1.png │ │ │ ├── combo-1.png │ │ │ ├── custom-1.png │ │ │ ├── distribution-1.png │ │ │ ├── ggplot-1.png │ │ │ ├── intercept-1.png │ │ │ ├── margins-1.png │ │ │ ├── marginsShort-1.png │ │ │ ├── marginsShort-2.png │ │ │ ├── multipleModels-1.png │ │ │ ├── regularExpression-1.png │ │ │ ├── relabel-1.png │ │ │ ├── secretWeapon-1.png │ │ │ ├── smallMultiple-1.png │ │ │ ├── smallMultiple2-1.png │ │ │ ├── stats-1.png │ │ │ ├── stats-2.png │ │ │ ├── stats-3.png │ │ │ ├── stats_compare-1.png │ │ │ ├── stats_compare-2.png │ │ │ ├── stats_custom-1.png │ │ │ ├── tidy-1.png │ │ │ └── tidyData-1.png │ │ ├── header-attrs-2.10.1 │ │ │ └── header-attrs.js │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.7 │ │ │ ├── header-attrs 2.js │ │ │ └── header-attrs.js │ ├── index.html │ ├── kl2007_examples.html │ └── kl2007_examples_files │ │ ├── figure-html │ │ ├── unnamed-chunk-2-1.png │ │ ├── unnamed-chunk-3-1.png │ │ ├── unnamed-chunk-4-1.png │ │ ├── unnamed-chunk-5-1.png │ │ ├── unnamed-chunk-6-1.png │ │ └── unnamed-chunk-7-1.png │ │ ├── header-attrs-2.10.1 │ │ └── header-attrs.js │ │ ├── header-attrs-2.10 │ │ └── header-attrs.js │ │ └── header-attrs-2.7 │ │ ├── header-attrs 2.js │ │ └── header-attrs.js ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── index.html ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── Rplot002.png │ ├── Rplot003.png │ ├── Rplot004.png │ ├── Rplot005.png │ ├── add_brackets-1.png │ ├── add_brackets.html │ ├── by_2sd.html │ ├── dwplot-1.png │ ├── dwplot-2.png │ ├── dwplot-3.png │ ├── dwplot-4.png │ ├── dwplot-5.png │ ├── dwplot.html │ ├── index.html │ ├── relabel_predictors-1.png │ ├── relabel_predictors-2.png │ ├── relabel_predictors.html │ ├── relabel_y_axis.html │ ├── secret_weapon-1.png │ ├── secret_weapon.html │ ├── small_multiple-1.png │ ├── small_multiple-2.png │ └── small_multiple.html └── sitemap.xml ├── dotwhisker.Rproj ├── man ├── add_brackets.Rd ├── by_2sd.Rd ├── dwplot.Rd ├── relabel_predictors.Rd ├── relabel_y_axis.Rd ├── secret_weapon.Rd └── small_multiple.Rd └── vignettes ├── dotwhisker-vignette.Rmd ├── kl2007_examples.Rmd └── vignette.bib /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^cran-comments.md$ 4 | ^developing\.R$ 5 | ^Rplots\.pdf$ 6 | ^plot\.pdf$ 7 | ^examples\.R$ 8 | ^R\add_headers.R$ 9 | ^developing-note.Rmd$ 10 | ^developing-note.nb.html$ 11 | ^README.md$ 12 | ^\.travis\.yml$ 13 | ^CONDUCT\.md$ 14 | ^dev$ 15 | ^doc$ 16 | ^docs$ 17 | ^Meta$ 18 | ^CRAN-RELEASE$ 19 | ^CRAN-SUBMISSION$ 20 | ^.github$ 21 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | inst/doc/*.html linguist-documentation 2 | -------------------------------------------------------------------------------- /.github/workflows/rhub.yaml: -------------------------------------------------------------------------------- 1 | # R-hub's generic GitHub Actions workflow file. It's canonical location is at 2 | # https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml 3 | # You can update this file to a newer version using the rhub2 package: 4 | # 5 | # rhub::rhub_setup() 6 | # 7 | # It is unlikely that you need to modify this file manually. 8 | 9 | name: R-hub 10 | run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}" 11 | 12 | on: 13 | workflow_dispatch: 14 | inputs: 15 | config: 16 | description: 'A comma separated list of R-hub platforms to use.' 17 | type: string 18 | default: 'linux,windows,macos' 19 | name: 20 | description: 'Run name. You can leave this empty now.' 21 | type: string 22 | id: 23 | description: 'Unique ID. You can leave this empty now.' 24 | type: string 25 | 26 | jobs: 27 | 28 | setup: 29 | runs-on: ubuntu-latest 30 | outputs: 31 | containers: ${{ steps.rhub-setup.outputs.containers }} 32 | platforms: ${{ steps.rhub-setup.outputs.platforms }} 33 | 34 | steps: 35 | # NO NEED TO CHECKOUT HERE 36 | - uses: r-hub/actions/setup@v1 37 | with: 38 | config: ${{ github.event.inputs.config }} 39 | id: rhub-setup 40 | 41 | linux-containers: 42 | needs: setup 43 | if: ${{ needs.setup.outputs.containers != '[]' }} 44 | runs-on: ubuntu-latest 45 | name: ${{ matrix.config.label }} 46 | strategy: 47 | fail-fast: false 48 | matrix: 49 | config: ${{ fromJson(needs.setup.outputs.containers) }} 50 | container: 51 | image: ${{ matrix.config.container }} 52 | 53 | steps: 54 | - uses: r-hub/actions/checkout@v1 55 | - uses: r-hub/actions/platform-info@v1 56 | with: 57 | token: ${{ secrets.RHUB_TOKEN }} 58 | job-config: ${{ matrix.config.job-config }} 59 | - uses: r-hub/actions/setup-deps@v1 60 | with: 61 | token: ${{ secrets.RHUB_TOKEN }} 62 | job-config: ${{ matrix.config.job-config }} 63 | - uses: r-hub/actions/run-check@v1 64 | with: 65 | token: ${{ secrets.RHUB_TOKEN }} 66 | job-config: ${{ matrix.config.job-config }} 67 | 68 | other-platforms: 69 | needs: setup 70 | if: ${{ needs.setup.outputs.platforms != '[]' }} 71 | runs-on: ${{ matrix.config.os }} 72 | name: ${{ matrix.config.label }} 73 | strategy: 74 | fail-fast: false 75 | matrix: 76 | config: ${{ fromJson(needs.setup.outputs.platforms) }} 77 | 78 | steps: 79 | - uses: r-hub/actions/checkout@v1 80 | - uses: r-hub/actions/setup-r@v1 81 | with: 82 | job-config: ${{ matrix.config.job-config }} 83 | token: ${{ secrets.RHUB_TOKEN }} 84 | - uses: r-hub/actions/platform-info@v1 85 | with: 86 | token: ${{ secrets.RHUB_TOKEN }} 87 | job-config: ${{ matrix.config.job-config }} 88 | - uses: r-hub/actions/setup-deps@v1 89 | with: 90 | job-config: ${{ matrix.config.job-config }} 91 | token: ${{ secrets.RHUB_TOKEN }} 92 | - uses: r-hub/actions/run-check@v1 93 | with: 94 | job-config: ${{ matrix.config.job-config }} 95 | token: ${{ secrets.RHUB_TOKEN }} 96 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .DS_Store 5 | developing-note.Rmd 6 | developing-note.nb.html 7 | vignettes/dotwhisker-vignette.R 8 | vignettes/dotwhisker-vignette.html 9 | vignettes/kl2007_examples.R 10 | vignettes/kl2007_examples.html 11 | doc 12 | Meta 13 | /doc/ 14 | /Meta/ 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /CRAN-SUBMISSION: -------------------------------------------------------------------------------- 1 | Version: 0.8.4 2 | Date: 2025-05-06 07:06:05 UTC 3 | SHA: 59f9c883585dc2fb326560c5f3bafcf99269ef89 4 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: dotwhisker 2 | Type: Package 3 | Title: Dot-and-Whisker Plots of Regression Results 4 | Version: 0.8.9999 5 | Authors@R: 6 | c(person("Frederick", "Solt", role = c("aut"), email = "frederick-solt@uiowa.edu"), 7 | person("Yue", "Hu", role = c("aut", "cre"), email = "yuehu@tsinghua.edu.cn"), 8 | person("Ben", "Bolker", role = "ctb", email = "bolker@mcmaster.ca"), 9 | person("Os", "Keyes", role = "ctb", email = "ironholds@gmail.com"), 10 | person("Stefan", "Müller", role = "ctb", email = "stefan.mueller@ucd.ie"), 11 | person("Thomas", "Leeper", role = "ctb", email = "thosjleeper@gmail.com"), 12 | person("Chris", "Wallace", role = "ctb", email = "cew54@cam.ac.uk"), 13 | person("Christopher", "Warshaw", role = "ctb", email = "warshaw@email.gwu.edu")) 14 | Maintainer: Yue Hu 15 | Description: Create quick and easy dot-and-whisker plots of regression results. It takes as input either (1) a coefficient table in standard form or (2) one (or a list of) fitted model objects (of any type that has methods implemented in the 'parameters' package). It returns 'ggplot' objects that can be further customized using tools from the 'ggplot2' package. The package also includes helper functions for tasks such as rescaling coefficients or relabeling predictor variables. See more methodological discussion of the visualization and data management methods used in this package in Kastellec and Leoni (2007) and Gelman (2008) . 16 | Encoding: UTF-8 17 | URL: https://fsolt.org/dotwhisker/ 18 | BugReports: https://github.com/fsolt/dotwhisker/issues 19 | Depends: 20 | R (>= 4.2.0), 21 | ggplot2 (>= 2.2.1), 22 | Imports: 23 | grid, 24 | gtable, 25 | gridExtra, 26 | stats, 27 | parameters, 28 | performance, 29 | patchwork, 30 | dplyr, 31 | stringr, 32 | ggstance, 33 | rlang, 34 | purrr, 35 | marginaleffects 36 | Suggests: 37 | ordinal, 38 | tibble, 39 | knitr, 40 | rmarkdown, 41 | broom 42 | License: MIT + file LICENSE 43 | LazyData: FALSE 44 | VignetteBuilder: knitr 45 | RoxygenNote: 7.3.2 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2015 2 | COPYRIGHT HOLDER: Frederick Solt, Yue HU 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(add_brackets) 4 | export(by_2sd) 5 | export(dwplot) 6 | export(relabel_predictors) 7 | export(relabel_y_axis) 8 | export(secret_weapon) 9 | export(small_multiple) 10 | import(ggplot2) 11 | import(gtable) 12 | import(marginaleffects) 13 | import(patchwork) 14 | import(performance) 15 | importFrom(dplyr,"%>%") 16 | importFrom(dplyr,across) 17 | importFrom(dplyr,arrange) 18 | importFrom(dplyr,bind_rows) 19 | importFrom(dplyr,distinct) 20 | importFrom(dplyr,ends_with) 21 | importFrom(dplyr,filter) 22 | importFrom(dplyr,full_join) 23 | importFrom(dplyr,group_by) 24 | importFrom(dplyr,if_else) 25 | importFrom(dplyr,left_join) 26 | importFrom(dplyr,mutate) 27 | importFrom(dplyr,n) 28 | importFrom(dplyr,one_of) 29 | importFrom(dplyr,relocate) 30 | importFrom(dplyr,rename) 31 | importFrom(dplyr,select) 32 | importFrom(dplyr,where) 33 | importFrom(ggstance,GeomLinerangeh) 34 | importFrom(ggstance,geom_pointrangeh) 35 | importFrom(ggstance,position_dodgev) 36 | importFrom(grid,gpar) 37 | importFrom(grid,linesGrob) 38 | importFrom(grid,textGrob) 39 | importFrom(grid,unit.pmax) 40 | importFrom(gridExtra,tableGrob) 41 | importFrom(gridExtra,ttheme_default) 42 | importFrom(parameters,parameters) 43 | importFrom(parameters,standardize_names) 44 | importFrom(purrr,list_c) 45 | importFrom(purrr,list_rbind) 46 | importFrom(purrr,map) 47 | importFrom(rlang,exprs) 48 | importFrom(stats,dnorm) 49 | importFrom(stats,model.frame) 50 | importFrom(stats,model.matrix) 51 | importFrom(stats,nobs) 52 | importFrom(stats,qnorm) 53 | importFrom(stats,reorder) 54 | importFrom(stats,sd) 55 | importFrom(stats,setNames) 56 | importFrom(utils,globalVariables) 57 | importFrom(utils,modifyList) 58 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | ## Version 0.8.4 2 | 3 | - Bring the `margin` function back based on Vincent Arel-Bundock's `marginaleffects`. 4 | 5 | ## Version 0.8.3 6 | 7 | - Add argument to turn on/off the toggle warnings and messages when showing the model fit table. 8 | - Fix error from CRAN 9 | 10 | ## Version 0.8.2 11 | 12 | - Submitted just for the upstream package (`prediction`) issue. 13 | - Removed `margins` for the author would not maintain or update it in the foreseeable future. 14 | 15 | ## Version 0.8.1 16 | 17 | Continue to remove the reference to `broomExtra` per CRAN's requirement (email on 2024-02-19) 18 | 19 | ## Version 0.8.0 20 | 21 | ### Bug fixed 22 | 23 | 1. Removed the reference to `broomExtra` per CRAN's requirement (email on 2024-01-23) 24 | 25 | ### New features 26 | 27 | 1. Adding the argument `show_stats` to `dwplot` and `small_multiple` to show model fits beneath the plot 28 | 2. Adding a hidden function `dw_stats` to extract model fits from the model outputs. 29 | 30 | ## Version 0.7.4 31 | 32 | ### Bug fixed 33 | 34 | 1. Allowing `model_order` accurately work when `relabel_predictors` is used. 35 | 2. Letting the vignette correctly shown. 36 | 37 | ## Version 0.7.3 38 | 39 | ### New features 40 | 41 | 1. Adding argument `model_order` and `submodel_order` in `small_multiple` to allow customizing the order of models to present. 42 | 2. Adding argument `axis_switch` in `small_multiple` to allow switching the positions of the variable labels and y axis ticks. 43 | 44 | ## Version 0.7.1 45 | 46 | ### Bug fixed 47 | 48 | 1. Fixed the error when setting `style = "distribution"`. Thanks for Indrajee @IndrajeetPatil pointing that out. 49 | 50 | ## Version 0.7.0 51 | 52 | ### New features 53 | 54 | 1. Adding argument `model_order` in `dwplot` to allow customizing the order of models to present. 55 | 2. Adding argument `fontSize` in `add_brackets` to allow customizing the font size of bracket labels, and opening possibility for users to further customize bracket labels. 56 | 3. Using the `parameters` instead of `broomExtra` as the plotting data frame creator. Thanks for the suggestion from @IndrajeetPatil. 57 | 58 | ### Bug fixed 59 | 60 | 1. Models and margins present in the correct order. 61 | 62 | ## Version 0.6.0 63 | 64 | ### New features 65 | 66 | 1. Adding changing the `dw_tidy` engine to `broomExtra::tidy_parapmeter`. 67 | 2. Adding the function to plot AME based on [`margins::margins`](https://CRAN.R-project.org/package=margins). 68 | 69 | ### Bug fixed 70 | 71 | 1. Allowing the data.frame output varying based on confidence intervals. 72 | 2. Setting the default value of `by_2sd` to FALSE. 73 | 74 | ## Version 0.5.0 75 | 76 | #### New features 77 | 78 | 1. The `vline` argument is now available for `dwplot()`. Passing a `geom_vline()` object to this argument, typically one with `xintercept = 0`, will plot this line _behind_ the plotted coefficients, which most will find aesthetically preferable. The default for this argument is `NULL`, so if you prefer not to include such lines or just like them plotted last and foremost, there's no need to change your code. 79 | 2. `dwplot()` now again accepts the `whisker_arg` argument to change the appearance of the whiskers representing the confidence intervals that has been lost since v0.3.0. This means you can, for example, specify different colors for the dots and the whiskers: 80 | 81 | ```r 82 | # load the library 83 | library(dotwhisker) 84 | #> Loading required package: ggplot2 85 | 86 | # linear model of interest 87 | lm_object <- stats::lm(formula = wt ~ am * cyl, data = mtcars) 88 | 89 | # creating the plot with dwplot 90 | dwplot(x = lm_object, 91 | dot_args = list(color = "red"), # color for the dot 92 | whisker_args = list(color = "black"), # color for the whisker 93 | vline = ggplot2::geom_vline(xintercept = 0, # put vline _behind_ coefs 94 | colour = "grey60", 95 | linetype = 2, 96 | size = 1)) 97 | ``` 98 | 99 | ![](https://i.imgur.com/Hr3ZOzF.png) 100 | 101 | Created on 2018-06-27 by the `reprex` package (v0.2.0). 102 | 103 | ## Version 0.4.1 104 | 105 | #### Bug fixes 106 | 107 | 1. Fixed a bug in `add_brackets()` that caused brackets to overlap in large models or when many models were included in a single plot. 108 | 109 | ## Version 0.4.0 110 | 111 | #### New features 112 | 113 | 1. A new plot style! Specifying `style = "distribution"` in the arguments to `dwplot()` presents regression coefficients as normal distributions, underscored with a line representing the desired confidence interval. 114 | 2. `relabel_predictors()` now conveniently _reorders_ the predictors as well. 115 | 3. `add_brackets()` can now be added directly to the end of a chain of commands that generate a dotwhisker plot; the intermediate object necessary in past versions is no longer needed. Just wrap the plotting commands in braces (`{` and `}`) before piping them to `add_brackets()`! 116 | 117 | #### Syntax changes 118 | 119 | 1. The `alpha` argument to `dwplot()` should no longer be used to change the width of confidence intervals; use `conf.int` (to be passed to `broom::tidy` via `...`) instead. 120 | 2. When `dwplot()` is passed model objects rather than a tidy data frame, the regression coefficients are now rescaled by two standard deviations of their respective variables in the analyzed data (per `by_2sd()`) by default. This may be changed by setting `by_2sd = FALSE`. 121 | 122 | #### Bug fixes 123 | 124 | 1. Fixed a bug in `add_brackets()` that de-centered the brackets 125 | 2. Fixed a bug that caused `dot_args` to be ignored after plots were passed to `relabel_predictors()` 126 | 3. Fixed a bug that prevented `small_multiple()` from directly reading confidence intervals from a model. 127 | 4. Fixed a bug in `by_2sd()` now adjusts, if present, any confidence intervals in tidy data frames passed to the function. 128 | 129 | Thanks to Steven V. Miller and Ryan Burge for bug reports, and to Ben Edwards and Jay Jacobs for inspiring `style = "distribution"`! 130 | 131 | ## Version 0.3.0 132 | 133 | 1. Rewrote the plotting functions based on the `ggstance` functions. The new `dwplot` allows cooperating with more `ggplot` functions, such as `facet_*`. 134 | 2. Drew whiskers based on the CI estimates directly from the model output. See more details in `tidy.lm` and `confint`. 135 | 3. Clarified the description of `by_2sd`. 136 | 137 | ## Version 0.2.6 138 | 139 | 1. Fixed the bug in `relabel_predictors`. 140 | 141 | ## Version 0.2.5 142 | 143 | 1. Expanded capabilities of `relabel_predictors`. `relabel_predictors` now accepts plots as well as tidy dataframes as input; that is, it may now be used both before and after calls to `dwplot`. 144 | 2. Deprecated `relabel_y_axis`. It is easy to mistakenly mislabel variables with `relabel_y_axis`, and it has a conflict with `add_brackets` in single-model plots. 145 | 3. Provided example of using multiple shapes for multiple models in vignette. 146 | 4. `dwplot` works for `polr` projects. 147 | 148 | ## Version 0.2.4 149 | 150 | 1. Improved the presentation of `small_multiple`. 151 | 152 | ## Version 0.2.3 153 | 154 | 1. Fixed the error of variable ordering with a single model. 155 | 156 | ## Version 0.2.2 157 | 158 | 1. Fixed the error in presenting multiple models. 159 | 160 | ## Version 0.2.1 161 | 162 | 1. Fixed the error due to the update of `dplyr::group_by` 163 | 2. Fixing the errors in vignette. 164 | 3. Adding the `show_intercept` argument. 165 | 4. Shorten the version number to three digits as `devtools` suggests. 166 | 167 | ## Version 0.2.0.5 168 | 169 | 1. Fixed the error due to the update of `gridExtra`. 170 | 2. Fixed the error due to the update of `ggplot2`. 171 | 172 | ## Version 0.2.0.4 173 | 174 | 1. Fixed presenting error in multilevel models (#44) 175 | 176 | ## Version 0.2.0.3 177 | 178 | 1. Fixed the link error in `kl2007_example.Rmd`. 179 | 180 | ## Version 0.2.0.2 181 | 182 | 1. Improving the vignette. 183 | 2. The function works for `ggplot2` 2.0.0. 184 | 185 | ## Version 0.2.0.1 186 | 187 | 1. Fixed the error in the vignette. 188 | 189 | ## Version 0.2.0.0 190 | 191 | 1. Allowing directly using model objects besides `tidy` data.frame. 192 | 2. Adding two new special plotting functions: `secret_weapon` and `small_multiple`. 193 | 3. Adding two graph adjusting functions: `relabel_predictor` and `relabel_y_axis`. 194 | 195 | More details about the new functions are available in the vignette. 196 | -------------------------------------------------------------------------------- /R/add_brackets.R: -------------------------------------------------------------------------------- 1 | #' Add Labelled Brackets to Group Predictors in a Dot-and-Whisker Plot 2 | #' 3 | #' \code{add_brackets} draws brackets along the y-axis beyond the plotting area of a dot-and-whisker plot generated by \code{dwplot}, useful for labelling groups of predictors 4 | #' 5 | #' @param p A plot generated by \code{dwplot}. Any `ggplot` customization should be done before passing the plot to \code{add_brackets}. To pass the finalized plot to \code{add_brackets} without creating an intermediate object, simply wrap the code that generates it in braces (\code{`{`} and \code{`}`}). 6 | #' @param brackets A list of brackets; each element of the list should be a character vector consisting of (1) a label for the bracket, (2) the name of the topmost variable to be enclosed by the bracket, and (3) the name of the bottom most variable to be enclosed by the bracket. 7 | #' @param fontSize A number defining the size of the bracket label. The default value is .7. 8 | #' @param face A typeface for the bracket labels; options are "plain", "bold", "italic", "oblique", and "bold.italic". 9 | #' @param \dots Extra arguments to pass to \code{\link[grid]{gpar}}. 10 | #' 11 | #' @details The brackets are drawn by `grid` functions. Apart from font size and typeface, users can customize the appearance of the bracket labels by setting `gpar` arguments in `add_brackets`. 12 | #' 13 | #' @return The function returns a \code{ggplot} object. 14 | #' 15 | #' @examples 16 | #' library(dplyr) 17 | #' m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars) 18 | #' two_brackets <- list(c("Engine", "Cylinder", "Displacement"), 19 | #' c("Not Engine", "Intercept", "Weight")) 20 | #' 21 | #' {dwplot(m1, show_intercept = TRUE) %>% 22 | #' relabel_predictors("(Intercept)" = "Intercept", 23 | #' wt = "Weight", 24 | #' cyl = "Cylinder", 25 | #' disp = "Displacement") + 26 | #' theme_bw() + xlab("Coefficient") + ylab("") + 27 | #' theme(legend.position="none") + 28 | #' geom_vline(xintercept = 0, colour = "grey50", linetype = 2)} %>% 29 | #' add_brackets(two_brackets) 30 | #' 31 | #' @import gtable 32 | #' @importFrom grid textGrob linesGrob gpar unit.pmax 33 | #' 34 | #' @export 35 | 36 | add_brackets <- function(p, brackets, fontSize = .7, face = "italic", ...) { 37 | y_ind <- term <- estimate <- ymax <- ymin <- x <- NULL # not functional, just for CRAN check 38 | 39 | coef_layer <- 0 40 | repeat { 41 | coef_layer <- coef_layer + 1 42 | if ("x" %in% names(layer_data(p, i = coef_layer))) break 43 | } 44 | 45 | if (p$args$style == "dotwhisker") { 46 | pd <- left_join(p$data %>% mutate(xx = signif(estimate, 9)), 47 | layer_data(p, i = coef_layer) %>% mutate(xx = signif(x, 9)), by = "xx") %>% 48 | left_join(layer_data(p, i = coef_layer - 1), 49 | by = c("colour", "y", "group", "PANEL", "ymin", "ymax", "xmax", "size", "alpha")) 50 | } else { 51 | pd <- left_join(p$data %>% mutate(xx = signif(estimate, 9)), 52 | layer_data(p, i = coef_layer) %>% mutate(xx = signif(x, 9)), by = "xx") 53 | pd <- pd %>% 54 | mutate(ymin = y_ind, 55 | ymax = y_ind) 56 | } 57 | overhang <- max(pd$y_ind)/30 58 | overhang <- ifelse(overhang > .23, .23, overhang) 59 | farout <- ifelse(p$args$style == "distribution", max(pd$x, na.rm = TRUE) + 100, max(pd$xmax, na.rm = TRUE) + 100) 60 | p1 <- p + theme(plot.margin = unit(c(1, 1, 1, -1), "lines")) + ylab("") 61 | 62 | if (!is.list(brackets)) stop('Error: argument "brackets" is not a list') 63 | 64 | draw_bracket_label <- function(x, fs = fontSize, f = face, ...) { 65 | top <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymax"] %>% max() 66 | bottom <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymin"] %>% min() 67 | shift <- max(abs(top - round(top)), abs(round(bottom) - bottom)) 68 | top <- round(top) + shift 69 | bottom <- round(bottom) - shift 70 | 71 | annotation_custom( 72 | grob = grid::textGrob(label = x[1], gp = grid::gpar(cex = fs, fontface = f, ...), rot = 90), 73 | xmin = farout, xmax = farout, 74 | ymin = (top + bottom)/2, ymax = (top + bottom)/2) 75 | } 76 | 77 | draw_bracket_vert <- function(x, oh = overhang) { 78 | top <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymax"] %>% max() 79 | bottom <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymin"] %>% min() 80 | shift <- min(max(abs(top - round(top)), abs(round(bottom) - bottom)) + oh, .45) 81 | top <- round(top) + shift 82 | bottom <- round(bottom) - shift 83 | 84 | annotation_custom(grob = grid::linesGrob(), 85 | xmin = farout + 0.5, xmax = farout + 0.5, 86 | ymin = bottom, ymax = top) 87 | } 88 | 89 | draw_bracket_top <- function(x, oh = overhang) { 90 | top <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymax"] %>% max() 91 | bottom <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymin"] %>% min() 92 | shift <- min(max(abs(top - round(top)), abs(round(bottom) - bottom)) + oh, .45) 93 | top <- round(top) + shift 94 | bottom <- round(bottom) - shift 95 | 96 | annotation_custom(grob = grid::linesGrob(), 97 | xmin = farout + 0.5, farout + 1, 98 | ymin = top, ymax = top) 99 | } 100 | 101 | draw_bracket_bottom <- function(x, oh = overhang) { 102 | top <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymax"] %>% max() 103 | bottom <- pd[which((pd$term == x[2] | pd$term == x[3]) & !is.na(pd$estimate)), "ymin"] %>% min() 104 | shift <- min(max(abs(top - round(top)), abs(round(bottom) - bottom)) + oh, .45) 105 | top <- round(top) + shift 106 | bottom <- round(bottom) - shift 107 | 108 | annotation_custom(grob = grid::linesGrob(), xmin = farout + 0.5, xmax = farout + 1, 109 | ymin = bottom, ymax = bottom) 110 | } 111 | 112 | p2 <- p1 + 113 | theme_bw() + 114 | theme(plot.title = element_text(colour = NA), 115 | axis.title.y = element_blank(), 116 | axis.title.x = element_text(colour = NA), 117 | axis.text.y = element_blank(), 118 | axis.text.x = element_text(colour = NA), 119 | panel.grid.major = element_blank(), 120 | panel.grid.minor = element_blank(), 121 | axis.ticks = element_line(colour = NA), 122 | panel.border = element_rect(colour = NA), 123 | strip.background = element_rect(colour = NA, fill = NA), 124 | strip.text.x = element_text(colour = NA), 125 | plot.margin = unit(c(1,0,2,0), "lines"), 126 | legend.background = element_rect(colour = NA), 127 | legend.key = element_rect(colour = NA), 128 | legend.text = element_text(colour = NA)) + 129 | coord_cartesian(xlim = c(farout - 1, farout + 1)) + 130 | theme(legend.position = "none") 131 | 132 | for (i in seq(length(brackets))) { 133 | p2 <- p2 + 134 | draw_bracket_label(brackets[[i]]) + 135 | draw_bracket_vert(brackets[[i]]) + 136 | draw_bracket_top(brackets[[i]]) + 137 | draw_bracket_bottom(brackets[[i]]) 138 | } 139 | 140 | plots <- list(p2, p1) 141 | grobs <- lapply(plots, function(x) ggplotGrob(x)) 142 | max_heights <- list(do.call(grid::unit.pmax, lapply(grobs, function(x) x$heights))) 143 | grobs[[1]]$heights <- max_heights[[1]] 144 | grobs[[2]]$heights <- max_heights[[1]] 145 | 146 | pp <- ggplot(data.frame(x = 0:1, y = 0:1), aes_string(x = "x", y = "y")) + 147 | scale_x_continuous(limits = c(0, 1), expand = c(0, 0)) + 148 | scale_y_continuous(limits = c(0, 1), expand = c(0, 0)) + 149 | theme_void() + 150 | labs(x = NULL, y = NULL) + 151 | draw_grob(grobs[[1]], 0, 1/9) + 152 | draw_grob(grobs[[2]], 1/9, 8/9) 153 | 154 | return(pp) 155 | } 156 | 157 | draw_grob <- function(grob, x, width) { 158 | layer(data = data.frame(x = NA), 159 | stat = StatIdentity, 160 | position = PositionIdentity, 161 | geom = GeomCustomAnn, 162 | inherit.aes = FALSE, 163 | params = list(grob = grob, 164 | xmin = x, 165 | xmax = width, 166 | ymin = 0, 167 | ymax = 1)) 168 | } 169 | -------------------------------------------------------------------------------- /R/by_2sd.R: -------------------------------------------------------------------------------- 1 | #' Rescale regression results by multiplying by 2 standard deviations 2 | #' 3 | #' \code{by_2sd} rescales regression results to facilitate making dot-and-whisker plots using \code{\link[dotwhisker]{dwplot}}. 4 | #' 5 | #' @param df A data frame including the variables \code{term} (names of independent variables), \code{estimate} (corresponding coefficient estimates), \code{std.error} (corresponding standard errors), and optionally \code{model} (when multiple models are desired on a single plot) such as generated those by \code{\link[broom]{tidy}}. 6 | #' @param dataset The data analyzed in the models whose results are recorded in \code{df}, or (preferably) the \emph{model matrix} used by the models in \code{df}; the information required for complex models can more easily be generated from the model matrix than from the original data set. In many cases the model matrix can be extracted from the original model via \code{\link{model.matrix}}. 7 | #' 8 | #' @details \code{by_2sd} multiplies the results from regression models saved as tidy data frames for predictors that are not binary by twice the standard deviation of these variables in the dataset analyzed. Standardizing in this way yields coefficients that are directly comparable to each other and to those for untransformed binary predictors (Gelman 2008) and so facilitates plotting using \code{\link[dotwhisker]{dwplot}}. Note that the current version of \code{by_2sd} does not subtract the mean (in contrast to Gelman's (2008) formula). However, all estimates and standard errors of the independent variables are the same as if the mean was subtracted. The only difference from Gelman (2008) is that for all variables in the model the intercept is shifted by the coefficient times the mean of the variable. 9 | #' 10 | #' An alternative available in some circumstances is to pass a model object to \code{arm::standardize} before passing the results to \code{\link[broom]{tidy}} and then on to \code{\link[dotwhisker]{dwplot}}. The advantages of \code{by_2sd} are that (1) it takes a tidy data frame as its input and so is not restricted to only those model objects that \code{standardize} accepts and (2) it is much more efficient because it operates on the parameters rather than refitting the original model with scaled data. 11 | #' 12 | #' 13 | #' @return A tidy data frame 14 | #' @examples 15 | #' library(broom) 16 | #' library(dplyr) 17 | #' 18 | #' data(mtcars) 19 | #' m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars) 20 | #' m1_df <- tidy(m1) %>% by_2sd(mtcars) # create data frame of rescaled regression results 21 | #' 22 | #' @references 23 | #' Gelman, Andrew. 2008. "Scaling Regression Inputs by Dividing by Two Standard Deviations." Statistics in Medicine, 27:2865-2873. 24 | #' 25 | #' @importFrom dplyr "%>%" 26 | #' @importFrom stats sd 27 | #' 28 | #' @export 29 | 30 | by_2sd <- function(df, dataset) { 31 | if (!"by_2sd" %in% names(df)) { 32 | sdX2 <- df$term %>% 33 | as.list() %>% 34 | lapply(function(x) { 35 | ## FIXME: meaningful error message if names not found? 36 | ## (e.g. some kind of model object for which model.matrix() 37 | ## is not available, and we have non-standard contrasts+interactions) ? 38 | if(any(grep(":", x)) && !x %in% names(dataset)) { 39 | ## find interactions; create interaction column if necessary 40 | first <- gsub(":.*", "", x) 41 | second <- gsub(".*:", "", x) 42 | dataset[[paste0(first,":",second)]] <- dataset[[first]]*dataset[[second]] 43 | } 44 | unmatched <- !x %in% names(dataset) 45 | dx <- dataset[[x]] 46 | ## dichotomous/unmatched variable? 47 | dich <- (unmatched || 48 | stats::na.omit(unique(dx)) %>% sort() %>% identical(c(0,1))) 49 | if (dich) 1 else 2*stats::sd(dataset[[x]], na.rm=TRUE) 50 | }) %>% 51 | unlist() 52 | 53 | df$estimate <- df$estimate * sdX2 54 | df$std.error <- df$std.error * sdX2 55 | if ("conf.high" %in% names(df)) { 56 | df$conf.high <- df$conf.high * sdX2 57 | df$conf.low <- df$conf.low * sdX2 58 | } 59 | df$by_2sd <- TRUE 60 | } 61 | return(df) 62 | } 63 | -------------------------------------------------------------------------------- /R/globals.R: -------------------------------------------------------------------------------- 1 | globalVariables(c( 2 | "estimate", 3 | "model", 4 | "conf.low", 5 | "conf.high", 6 | "term", 7 | "std.error", 8 | "n", 9 | "loc", 10 | "dens", 11 | "AME", 12 | "SE", 13 | "lower", 14 | "p", 15 | "upper", 16 | "z" 17 | )) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /R/relabel_predictors.R: -------------------------------------------------------------------------------- 1 | #' Relabel the Predictors in a Tidy Data Frame of Regression Results 2 | #' 3 | #' \code{relabel_predictors} is a convenience function for relabeling the predictors in a tidy data frame to be passed to \code{\link[dotwhisker]{dwplot}} or a plot generated by \code{\link[dotwhisker]{dwplot}} 4 | #' 5 | #' @param x Either a tidy data frame to be passed to \code{\link[dotwhisker]{dwplot}} or a plot generated by \code{\link[dotwhisker]{dwplot}}. 6 | #' @param ... Named replacements, as in \code{\link[dplyr]{recode}}. The argument names should be the current values to be replaced, and the argument values should be the new (replacement) values. For backwards compatibility, a named character vector, with new values as values, and old values as names may also be used. The order of the named replacements will be preserved, so this function also serves the purpose of reordering variables. 7 | #' 8 | #' @return The function returns an object of the same type as it is passed: a tidy data frame or a plot generated by \code{\link[dotwhisker]{dwplot}}. 9 | #' 10 | #' @examples 11 | #' library(broom) 12 | #' library(dplyr) 13 | #' 14 | #' data(mtcars) 15 | #' m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars) 16 | #' m1_df <- broom::tidy(m1) %>% 17 | #' relabel_predictors("(Intercept)" = "Intercept", 18 | #' wt = "Weight", 19 | #' disp = "Displacement", 20 | #' cyl = "Cylinder") 21 | #' dwplot(m1_df) 22 | #' 23 | #' dwplot(m1, show_intercept = TRUE) %>% 24 | #' relabel_predictors("(Intercept)" = "Intercept", 25 | #' wt = "Weight", 26 | #' disp = "Displacement", 27 | #' cyl = "Cylinder") 28 | #' 29 | #' 30 | #' @importFrom dplyr select one_of arrange 31 | #' @importFrom rlang exprs 32 | #' @importFrom stats setNames 33 | #' 34 | #' @export 35 | 36 | relabel_predictors <- function(x, ...) { 37 | model <- term <- y_ind <- NULL # Set to NULL to make R CMD check happy 38 | 39 | dots <- rlang::exprs(...) 40 | if (is.language(dots[[1]])) { # if a named vector is passed, 41 | dots <- stats::setNames(as.list(...), names(...)) # convert it to a list 42 | } 43 | 44 | if (is.data.frame(x)) { 45 | if ("model" %in% names(x)) { 46 | x <- arrange(x, model, match(term, names(dots))) 47 | x$term <- factor(x$term, levels = unique(x$term)) 48 | } else { 49 | x <- arrange(x, match(term, names(dots))) 50 | x$term <- factor(x$term, levels = unique(x$term)) 51 | } 52 | x$term <- dplyr::recode(x$term, !!! dots) 53 | return(x) 54 | } 55 | else if (is.ggplot(x)) { 56 | m <- if ("model" %in% names(x$data)) x$data$model else NULL 57 | x$data <- arrange(x$data, m, match(term, names(dots))) %>% 58 | select(-y_ind) %>% 59 | filter(!is.na(term)) %>% 60 | mutate(across(term, \(x) factor(x, levels = unique(x)))) 61 | 62 | x$data$term <- dplyr::recode(x$data$term, !!! dots) 63 | 64 | args_list <- list(x = x$data, x$args) 65 | 66 | args_list <- x$args 67 | args_list$x <- x$data 68 | args_list$vars_order <- NULL # removing the vars_order since the var names are already changed 69 | 70 | p <- do.call(dwplot, args_list) 71 | return(p) 72 | } else stop("x should be either a tidy data frame or a plot generated by dwplot") 73 | } 74 | 75 | -------------------------------------------------------------------------------- /R/relabel_y_axis.R: -------------------------------------------------------------------------------- 1 | #' Relabel the Y-Axis of a Dot-Whisker Plot 2 | #' 3 | #' \code{relabel_y_axis} DEPRECATED. A convenience function for relabeling the predictors on the y-axis of a dot-whisker plot created by \code{\link[dotwhisker]{dwplot}}. It is deprecated; use \code{\link[dotwhisker]{relabel_predictors}} instead. 4 | #' 5 | #' @param x A vector of labels for predictors, listed from top to bottom 6 | #' 7 | #' @returns The function returns an object of the same type as it is passed: a plot generated by \code{\link[dotwhisker]{dwplot}}. 8 | #' 9 | #' @seealso \code{\link[dotwhisker]{relabel_predictors}} to relabel predictors on the y-axis of a dot-whisker plot or in a tidy data.frame 10 | #' 11 | #' 12 | #' @export 13 | 14 | relabel_y_axis <- function(x) { 15 | scale_y_continuous(breaks = length(x):1, labels = x) 16 | } 17 | -------------------------------------------------------------------------------- /R/secret_weapon.R: -------------------------------------------------------------------------------- 1 | #' Generate a 'Secret Weapon' Plot of Regression Results from Multiple Models 2 | #' 3 | #' \code{secret_weapon} is a function for plotting regression results of multiple models as a 'secret weapon' plot 4 | #' 5 | #' @param x Either a model object to be tidied with \code{\link[broom]{tidy}}, or a list of such model objects, or a tidy data frame of regression results (see 'Details'). 6 | #' @param ci A number indicating the level of confidence intervals; the default is .95. 7 | #' @param margins A logical value indicating whether presenting the average marginal effects of the estimates. See the Details of \code{dwplot} for more information. 8 | #' @param var The predictor whose results are to be shown in the 'secret weapon' plot 9 | #' @param by_2sd When x is a list of model objects, should the coefficients for predictors that are not binary be rescaled by twice the standard deviation of these variables in the dataset analyzed, per Gelman (2008)? Defaults to \code{TRUE}. Note that when x is a tidy data frame, one can use \code{\link[dotwhisker]{by_2sd}} to rescale similarly. 10 | #' @param \dots Arguments to pass to \code{\link[dotwhisker]{dwplot}}. 11 | #' 12 | #' @details 13 | #' Andrew Gelman has coined the term "the secret weapon" for dot-and-whisker plots that compare the estimated coefficients for a single predictor across many models or datasets. 14 | #' \code{secret_weapon} takes a tidy data frame of regression results or a list of model objects and generates a dot-and-whisker plot of the results of a single variable across the multiple models. 15 | #' 16 | #' Tidy data frames to be plotted should include the variables \code{term} (names of predictors), \code{estimate} (corresponding estimates of coefficients or other quantities of interest), \code{std.error} (corresponding standard errors), and \code{model} (identifying the corresponding model). 17 | #' In place of \code{std.error} one may substitute \code{lb} (the lower bounds of the confidence intervals of each estimate) and \code{ub} (the corresponding upper bounds). 18 | #' 19 | #' Alternately, \code{secret_weapon} accepts as input a list of model objects that can be tidied by \code{\link[broom]{tidy}} (or \code{\link[parameters]{parameters}} (with proper formatting)), or a list of such model objects. 20 | #' 21 | #' @return The function returns a \code{ggplot} object. 22 | #' 23 | #' @examples 24 | #' 25 | #' library(dplyr) 26 | #' library(broom) 27 | #' 28 | #' # Estimate models across many samples, put results in a tidy data frame 29 | #' by_clarity <- diamonds %>% group_by(clarity) %>% 30 | #' do(tidy(lm(price ~ carat + cut + color, data = .))) %>% 31 | #' ungroup %>% rename(model = clarity) 32 | #' 33 | #' # Generate a 'secret weapon' plot of the results of diamond size 34 | #' secret_weapon(by_clarity, "carat") 35 | #' 36 | #' 37 | #' @importFrom dplyr "%>%" filter select rename 38 | #' @importFrom utils globalVariables 39 | #' 40 | #' @export 41 | 42 | secret_weapon <- function(x, var = NULL, ci = .95, margins = FALSE, by_2sd = FALSE, ...) { 43 | # If x is list of model objects, convert to a tidy data frame 44 | if (!"data.frame" %in% class(x)) { 45 | df <- dw_tidy(x, ci, by_2sd) 46 | } else { 47 | df <- x 48 | } 49 | 50 | # Set variables that will appear in pipelines to NULL to make R CMD check happy 51 | term <- model <- NULL 52 | 53 | n_vars <- length(unique(df$term)) 54 | 55 | # Confirm number of models, get model names 56 | if ("model" %in% names(df)) { 57 | n_models <- length(unique(df$model)) 58 | } else { 59 | if (length(df$term) == n_vars) { 60 | stop("The 'secret weapon' is used to compare results for a single predictor across different models; please submit results from more than one model") 61 | } else { 62 | stop("Please add a variable named 'model' to distinguish different models") 63 | } 64 | } 65 | mod_names <- unique(df$model) 66 | 67 | df <- df %>% filter(term == var) %>% select(-term) %>% rename(term = model) 68 | p <- df %>% dwplot(...) 69 | return(p) 70 | } 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [![CRAN version](http://www.r-pkg.org/badges/version/dotwhisker)](https://cran.r-project.org/web/packages/dotwhisker/index.html) ![](http://cranlogs.r-pkg.org/badges/grand-total/dotwhisker) [![Travis-CI Build Status](https://travis-ci.org/fsolt/dotwhisker.svg?branch=master)](https://travis-ci.org/fsolt/dotwhisker) 4 | 5 | ------------------------------------------------------------------------ 6 | dotwhisker 7 | ========= 8 | 9 | `dotwhisker` is an R package for quickly and easily generating dot-and-whisker plots of regression results, either directly from model objects or from tidy data frames. It provides a convenient way to create highly customizable plots for presenting and comparing statistics. It can be used to plot coefficients or other estimates (e.g., predicted probabilities) within a model or compare them across different models. The estimates are presented as dots with confidence interval whiskers, and predictors can be grouped in brackets. 10 | 11 | To install: 12 | 13 | * the latest release version: `install.packages("dotwhisker")`. 14 | * the latest development version: `if (!require("remotes")) install.packages("remotes"); remotes::install_github("fsolt/dotwhisker")`. 15 | 16 | 17 | More details are available at here: 18 | 19 | https://cran.r-project.org/web/packages/dotwhisker/vignettes/dotwhisker-vignette.html 20 | 21 | 22 | Please note that this project is released with a [Contributor Code of Conduct](https://github.com/fsolt/dotwhisker/blob/master/CONDUCT.md). By participating in this project you agree to abide by its terms. 23 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | 3 | * Local OS X install, R 4.2.0 4 | * Ubuntu 22.04.4 LTS, R 4.2.2 5 | * Win-builder R Under development (unstable) (2024-06-25 r86831 ucrt) 6 | 7 | ## R CMD check results 8 | 0 errors | 0 warnings | 0 notes 9 | -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/_extension.yml: -------------------------------------------------------------------------------- 1 | title: Journal of Statistical Software Format 2 | author: Charles Teague 3 | version: 0.9.4 4 | quarto-required: ">=1.2.198" 5 | contributes: 6 | format: 7 | common: 8 | filters: 9 | - jss.lua 10 | shortcodes: 11 | - quarto-ext/fancy-text 12 | knitr: 13 | opts_chunk: 14 | R.options: 15 | prompt: "R> " 16 | continue: "+" 17 | pdf: 18 | documentclass: jss 19 | shift-heading-level-by: -1 20 | tbl-cap-location: bottom 21 | highlight-style: none 22 | include-in-header: 23 | text: | 24 | \usepackage{orcidlink,thumbpdf,lmodern} 25 | 26 | \newcommand{\class}[1]{`\code{#1}'} 27 | \newcommand{\fct}[1]{\code{#1()}} 28 | fig-width: 4.9 # 6.125" * 0.8, as in template 29 | fig-height: 3.675 # 4.9 * 3:4 30 | template-partials: 31 | - "partials/title.tex" 32 | - "partials/before-body.tex" 33 | - "partials/_print-address.tex" 34 | - "partials/_print-author.tex" 35 | cite-method: natbib 36 | biblio-config: false 37 | format-resources: 38 | - jss.bst 39 | - jss.cls 40 | - jsslogo.jpg 41 | html: 42 | number-sections: true 43 | toc: true 44 | -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/_extensions/quarto-ext/fancy-text/_extension.yml: -------------------------------------------------------------------------------- 1 | title: Fancy Text 2 | author: "RStudio, PBC" 3 | version: 0.0.1 4 | contributes: 5 | shortcodes: 6 | - fancy-text.lua 7 | -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/_extensions/quarto-ext/fancy-text/fancy-text.lua: -------------------------------------------------------------------------------- 1 | -- shortcode that provides a nicely formatted 'LaTeX' string 2 | function latex() 3 | if quarto.doc.is_format("pdf") then 4 | return pandoc.RawBlock('tex', '{\\LaTeX}') 5 | elseif quarto.doc.is_format("html") then 6 | return pandoc.Math('InlineMath', "\\LaTeX") 7 | else 8 | return pandoc.Span('LaTeX') 9 | end 10 | end 11 | 12 | -- shortcode that provides a nicely formatted 'bibtex' string 13 | function bibtex() 14 | if quarto.doc.is_format("pdf") then 15 | return pandoc.RawBlock('tex', '\\textsc{Bib}{\\TeX}') 16 | elseif quarto.doc.is_format("html") then 17 | return pandoc.RawBlock('html', 'BibTEX') 18 | else 19 | return pandoc.Span('BibTeX') 20 | end 21 | end -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/jss.lua: -------------------------------------------------------------------------------- 1 | -- these classes, when placed on a span will be replaced 2 | -- with an identical LaTeX command for PDF output 3 | local texMappings = { 4 | "proglang", 5 | "pkg", 6 | "fct", 7 | "class" 8 | } 9 | 10 | -- layout and style 11 | local kTypes = pandoc.List({'article', 'codesnippet', 'bookreview', 'softwarereview'}) 12 | local kSuppress = pandoc.List({'title', 'headings', 'footer'}) 13 | 14 | local function setClassOption(meta, option) 15 | if meta['classoption'] == nil then 16 | meta['classoption'] = pandoc.List({}) 17 | end 18 | 19 | meta['classoption']:insert({ pandoc.Str(option)}) 20 | end 21 | 22 | local function printList(list) 23 | local result = '' 24 | local sep = '' 25 | for i,v in ipairs(list) do 26 | result = result .. sep .. v 27 | sep = ', ' 28 | end 29 | return result 30 | end 31 | 32 | return { 33 | { 34 | Span = function(el) 35 | -- read the span contents and emit correct output 36 | local contentStr = pandoc.utils.stringify(el.content) 37 | 38 | for i, mapping in ipairs(texMappings) do 39 | if #el.attr.classes == 1 and el.attr.classes:includes(mapping) then 40 | if quarto.doc.is_format("pdf") then 41 | return pandoc.RawInline("tex", "\\" .. mapping .. "{" .. contentStr .. "}" ) 42 | else 43 | return pandoc.Code(contentStr); 44 | end 45 | end 46 | end 47 | end, 48 | Meta = function(meta) 49 | if quarto.doc.is_format("pdf") then 50 | -- Authors output in the template uses a special separator 51 | -- to join authors (including wrapping to a new line) 52 | -- this computes the proper prefix and places it in the author metadata 53 | -- for use by the template 54 | local byAuthor = meta['by-author'] 55 | if byAuthor ~= nil then 56 | for i, author in ipairs(byAuthor) do 57 | local prefix = {pandoc.RawInline("tex ","")}; 58 | if i > 1 and i % 2 == 1 then 59 | prefix = {pandoc.RawInline("tex", "\\AND")} 60 | elseif i > 1 then 61 | prefix = {pandoc.RawInline("tex", "\\And")} 62 | end 63 | author['metadata']['latex-prefix'] = prefix 64 | end 65 | end 66 | 67 | -- read the journal settings 68 | local journal = meta['journal'] 69 | local type = nil 70 | local shortnames = nil 71 | local suppress = nil 72 | local jss = nil 73 | 74 | if journal ~= nil then 75 | type = journal['type'] 76 | shortnames = journal['cite-shortnames'] 77 | suppress = journal['suppress'] 78 | jss = journal['include-jss-layout'] 79 | end 80 | 81 | -- process the type 82 | if type ~= nil then 83 | type = pandoc.utils.stringify(type) 84 | if kTypes:includes(type) then 85 | setClassOption(meta, type) 86 | else 87 | error("Unknown type " .. type .. "\nPlease use one of " .. printList(kTypes)) 88 | end 89 | else 90 | setClassOption(meta, 'article') 91 | end 92 | 93 | -- process the citation variant 94 | if shortnames == true then 95 | setClassOption(meta, 'shortnames') 96 | end 97 | 98 | -- process the suppressed parts 99 | if suppress ~= nil then 100 | for i,v in ipairs(suppress) do 101 | s = pandoc.utils.stringify(v) 102 | if kSuppress:includes(s) then 103 | setClassOption(meta, 'no' .. s) 104 | else 105 | error("Unknown suppressed part " .. s .. "\nPlease use one of " .. printList(kSuppress)) 106 | end 107 | end 108 | end 109 | 110 | -- process switch for JSS layout 111 | if jss == false then 112 | setClassOption(meta, 'nojss') 113 | end 114 | 115 | -- make sure there is a plain title 116 | if meta['title'] ~= nil and meta['title-plain'] == nil then 117 | meta['title-plain'] = pandoc.utils.stringify(meta['title']) 118 | end 119 | end 120 | 121 | return meta 122 | end 123 | } 124 | } -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/jsslogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/dev/jss/_extensions/jss/jsslogo.jpg -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/partials/_print-address.tex: -------------------------------------------------------------------------------- 1 | $it.name.literal$\\$if(it.affiliations/first)$$for(it.affiliations/first)$$if(it.department)$ 2 | 3 | $it.department$\\$endif$$if(it.address)$ 4 | 5 | $it.address$\\$endif$$if(it.city)$ 6 | 7 | $it.city$$endif$$if(it.state)$ $it.state$$endif$$if(it.country)$ $it.country$$endif$$if(it.city)$\\$elseif(it.state)$\\$elseif(it.country)$\\$endif$$endfor$$endif$$if(it.phone)$ 8 | 9 | Telephone: $it.phone$\\$endif$$if(it.fax)$ 10 | 11 | Fax: $it.fax$\\$endif$$if(it.email)$ 12 | 13 | E-mail: \email{$it.email$}\\$endif$$if(it.url)$ 14 | 15 | URL: \url{$it.url$}\\$endif$ 16 | 17 | \\~ 18 | 19 | -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/partials/_print-author.tex: -------------------------------------------------------------------------------- 1 | $if(it.metadata.latex-prefix)$ $it.metadata.latex-prefix$ $endif$$it.name.literal$$if(it.orcid)$~\orcidlink{$it.orcid$}$endif$$for(it.affiliations/first)$\\$it.name$$endfor$ -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/partials/before-body.tex: -------------------------------------------------------------------------------- 1 | $if(has-frontmatter)$ 2 | \frontmatter 3 | $endif$ 4 | $if(title)$ 5 | \maketitle 6 | $endif$ 7 | -------------------------------------------------------------------------------- /dev/jss/_extensions/jss/partials/title.tex: -------------------------------------------------------------------------------- 1 | %% -- Article metainformation (author, title, ...) ----------------------------- 2 | 3 | %% Author information 4 | \author{$for(by-author)$$_print-author.tex()$$endfor$} 5 | \Plainauthor{$for(by-author)$$it.name.literal$$sep$, $endfor$} %% comma-separated 6 | 7 | \title{$title$} 8 | $if(title-plain)$ 9 | \Plaintitle{$title-plain$} %% without formatting 10 | $endif$ 11 | $if(short-title)$ 12 | \Shorttitle{$short-title$} %% a short title (if necessary) 13 | $endif$ 14 | 15 | %% an abstract and keywords 16 | $if(abstract)$ 17 | \Abstract{$abstract$} 18 | $endif$ 19 | 20 | %% at least one keyword must be supplied 21 | $if(keywords-formatted)$ 22 | \Keywords{$for(keywords-formatted)$$it$$sep$, $endfor$} 23 | $endif$ 24 | $if(keywords)$ 25 | \Plainkeywords{$for(keywords)$$it$$sep$, $endfor$} 26 | $endif$ 27 | 28 | %% publication information 29 | %% NOTE: Typically, this can be left commented and will be filled out by the technical editor 30 | %% \Volume{50} 31 | %% \Issue{9} 32 | %% \Month{June} 33 | %% \Year{2012} 34 | %% \Submitdate{2012-06-04} 35 | %% \Acceptdate{2012-06-04} 36 | %% \setcounter{page}{1} 37 | %% \Pages{1--xx} 38 | 39 | %% The address of (at least) one author should be given 40 | %% in the following format: 41 | $if(by-author)$ 42 | \Address{ 43 | $for(by-author)$$_print-address.tex()$$endfor$ 44 | } 45 | $endif$ 46 | -------------------------------------------------------------------------------- /dev/jss/dotwhisker.bib: -------------------------------------------------------------------------------- 1 | % Encoding: UTF-8 2 | 3 | @Article{Kastellec2007, 4 | Title = {Using Graphs Instead of Tables in Political Science}, 5 | Author = {Kastellec, Jonathan P. and Leoni, Eduardo L.}, 6 | Journal = {Perspectives on Politics}, 7 | Year = {2007}, 8 | Number = {4}, 9 | Pages = {755--771}, 10 | Volume = {5}, 11 | } 12 | 13 | @Article{Gelman2008, 14 | Title = {Scaling Regression Inputs by Dividing by Two Standard Deviations}, 15 | Author = {Gelman, Andrew}, 16 | Journal = {Statistics in medicine}, 17 | Year = {2008}, 18 | Number = {15}, 19 | Pages = {2865--2873}, 20 | Volume = {27} 21 | } 22 | 23 | @Article{Gelman2002, 24 | title={Let's Practice What We Preach: Turning Tables into Graphs}, 25 | author={Gelman, Andrew and Pasarica, Cristian and Dodhia, Rahul}, 26 | journal={American Statistician}, 27 | volume={56}, 28 | number={2}, 29 | pages={121--130}, 30 | year={2002} 31 | } 32 | 33 | @Book{Wickham2009, 34 | title = {{ggplot2}: Elegant Graphics for Data Analysis}, 35 | publisher = {Springer}, 36 | year = {2009}, 37 | author = {Hadley Wickham}, 38 | address = {New York}, 39 | isbn = {978-0-387-98140-6}, 40 | url = {https://ggplot2-book.org/} 41 | } 42 | 43 | @Manual{Robinson2015, 44 | title = {{broom}: Convert Statistical Analysis Objects into Tidy Data Frames}, 45 | author = {David Robinson}, 46 | year = {2015}, 47 | note = {R package version 0.3.7}, 48 | url = {https://CRAN.R-project.org/package=broom} 49 | } 50 | 51 | 52 | @unpublished{Edwards2016, 53 | Author = {Edwards, Benjamin and Jacobs, Jay and Forrest, Stephanie}, 54 | Date-Added = {2018-04-10 14:53:45 +0000}, 55 | Date-Modified = {2018-04-10 15:00:15 +0000}, 56 | Note = {Pre-print}, 57 | Title = {Risky Business: Assessing Security with External Measurements}, 58 | Year = {2016}, 59 | } 60 | -------------------------------------------------------------------------------- /dev/jss/jss_dotwhisker.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/dev/jss/jss_dotwhisker.pdf -------------------------------------------------------------------------------- /dev/jss/jsslogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/dev/jss/jsslogo.jpg -------------------------------------------------------------------------------- /dev/runBeforeRelease.R: -------------------------------------------------------------------------------- 1 | # Check List for A New Release 2 | 3 | ## Vignette building 4 | 5 | devtools::install(build_vignettes = TRUE) 6 | pkgdown::build_site() 7 | 8 | ## Spell checking 9 | 10 | library(devtools) 11 | library(roxygen2) 12 | 13 | spell_check() 14 | 15 | rhub::rhub_check() 16 | 17 | ## Run the CRAN check 18 | # 1. Under the `Build` tab 19 | # 1. Fixed all the errors and warnings 20 | 21 | ## Documentation 22 | 23 | # 1. Update the version number in `DESCRIPTION` 24 | # 1. Update `NEWS` 25 | 26 | ## Removing the htmls to release space 27 | 28 | library(here) 29 | 30 | ls_html <- 31 | list.files(here("inst/tutorials"), 32 | pattern = "*.html$", 33 | recursive = TRUE, 34 | full.names = TRUE) 35 | 36 | file.remove(ls_html) 37 | 38 | ## Release 39 | 40 | devtools::release() 41 | 42 | ## Change the version number in `DESCRIPTION` back to the dev version (i.e., "9999") 43 | 44 | ## Post the Release note when the package is on CRAN 45 | 46 | 47 | ## (No need if the package already has a website) Package website building 48 | library(devtools) 49 | 50 | usethis::git_vaccinate() #Adds .DS_Store, .Rproj.user, .Rdata, .Rhistory, and .httr-oauth to your global (a.k.a. user-level) .gitignore. This is good practice as it decreases the chance that you will accidentally leak credentials to GitHub. 51 | 52 | use_github_links() 53 | use_github_action_check_standard() 54 | 55 | library(pkgdown) 56 | build_site() 57 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • dotwhisker 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 |
24 |
76 | 77 | 78 | 79 | 80 |
81 |
82 | 85 | 86 | Content not found. Please use links in the navbar. 87 | 88 |
89 | 90 | 94 | 95 |
96 | 97 | 98 | 99 |
103 | 104 |
105 |

106 |

Site built with pkgdown 2.1.1.

107 |
108 | 109 |
110 |
111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /docs/CONDUCT.html: -------------------------------------------------------------------------------- 1 | 2 | Contributor Code of Conduct • dotwhisker 6 | 7 | 8 |
9 |
53 | 54 | 55 | 56 |
57 |
58 | 61 | 62 |
63 | 64 |

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

65 |

We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

66 |

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

67 |

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

68 |

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

69 |

This Code of Conduct is adapted from the Contributor Covenant (http:contributor-covenant.org), version 1.0.0, available at http://contributor-covenant.org/version/1/0/0/

70 |
71 | 72 |
73 | 74 | 77 | 78 |
79 | 80 | 81 | 82 |
85 | 86 |
87 |

Site built with pkgdown 2.1.1.

88 |
89 | 90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | License • dotwhisker 6 | 7 | 8 |
9 |
53 | 54 | 55 | 56 |
57 |
58 | 61 | 62 |
YEAR: 2015
63 | COPYRIGHT HOLDER: Frederick Solt, Yue HU
64 | 
65 | 66 |
67 | 68 | 71 | 72 |
73 | 74 | 75 | 76 |
79 | 80 |
81 |

Site built with pkgdown 2.1.1.

82 |
83 | 84 |
85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/basic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/basic-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/brackets-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/brackets-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/by2sd-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/by2sd-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/ci-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/ci-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/clm-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/clm-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/combo-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/combo-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/custom-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/custom-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/distribution-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/distribution-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/ggplot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/ggplot-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/intercept-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/intercept-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/margins-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/margins-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/marginsShort-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/marginsShort-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/marginsShort-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/marginsShort-2.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/multipleModels-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/multipleModels-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/regularExpression-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/regularExpression-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/relabel-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/relabel-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/secretWeapon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/secretWeapon-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/smallMultiple-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/smallMultiple-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/smallMultiple2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/smallMultiple2-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/stats-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/stats-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/stats-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/stats-2.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/stats-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/stats-3.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/stats_compare-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/stats_compare-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/stats_compare-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/stats_compare-2.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/stats_custom-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/stats_custom-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/tidy-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/tidy-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/figure-html/tidyData-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/dotwhisker-vignette_files/figure-html/tidyData-1.png -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/header-attrs-2.10.1/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/header-attrs-2.7/header-attrs 2.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/dotwhisker-vignette_files/header-attrs-2.7/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | Articles • dotwhisker 6 | 7 | 8 |
9 |
53 | 54 | 55 | 56 |
57 |
58 | 61 | 62 | 71 |
72 |
73 | 74 | 75 |
78 | 79 |
80 |

Site built with pkgdown 2.1.1.

81 |
82 | 83 |
84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/articles/kl2007_examples_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/header-attrs-2.10.1/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/header-attrs-2.7/header-attrs 2.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/kl2007_examples_files/header-attrs-2.7/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | Authors and Citation • dotwhisker 6 | 7 | 8 |
9 |
53 | 54 | 55 | 56 |
57 |
58 |
59 | 62 | 63 | 64 |
  • 65 |

    Frederick Solt. Author. 66 |

    67 |
  • 68 |
  • 69 |

    Yue Hu. Author, maintainer. 70 |

    71 |
  • 72 |
  • 73 |

    Ben Bolker. Contributor. 74 |

    75 |
  • 76 |
  • 77 |

    Os Keyes. Contributor. 78 |

    79 |
  • 80 |
  • 81 |

    Stefan Müller. Contributor. 82 |

    83 |
  • 84 |
  • 85 |

    Thomas Leeper. Contributor. 86 |

    87 |
  • 88 |
  • 89 |

    Chris Wallace. Contributor. 90 |

    91 |
  • 92 |
  • 93 |

    Christopher Warshaw. Contributor. 94 |

    95 |
  • 96 |
97 |
98 |
99 |

Citation

100 | Source: DESCRIPTION 101 |
102 |
103 | 104 | 105 |

Solt F, Hu Y (2024). 106 | dotwhisker: Dot-and-Whisker Plots of Regression Results. 107 | R package version 0.8.3, https://fsolt.org/dotwhisker/. 108 |

109 |
@Manual{,
110 |   title = {dotwhisker: Dot-and-Whisker Plots of Regression Results},
111 |   author = {Frederick Solt and Yue Hu},
112 |   year = {2024},
113 |   note = {R package version 0.8.3},
114 |   url = {https://fsolt.org/dotwhisker/},
115 | }
116 | 117 |
118 | 119 |
120 | 121 | 122 | 123 |
126 | 127 |
128 |

Site built with pkgdown 2.1.1.

129 |
130 | 131 |
132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /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.css: -------------------------------------------------------------------------------- 1 | /* Docsearch -------------------------------------------------------------- */ 2 | /* 3 | Source: https://github.com/algolia/docsearch/ 4 | License: MIT 5 | */ 6 | 7 | .algolia-autocomplete { 8 | display: block; 9 | -webkit-box-flex: 1; 10 | -ms-flex: 1; 11 | flex: 1 12 | } 13 | 14 | .algolia-autocomplete .ds-dropdown-menu { 15 | width: 100%; 16 | min-width: none; 17 | max-width: none; 18 | padding: .75rem 0; 19 | background-color: #fff; 20 | background-clip: padding-box; 21 | border: 1px solid rgba(0, 0, 0, .1); 22 | box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); 23 | } 24 | 25 | @media (min-width:768px) { 26 | .algolia-autocomplete .ds-dropdown-menu { 27 | width: 175% 28 | } 29 | } 30 | 31 | .algolia-autocomplete .ds-dropdown-menu::before { 32 | display: none 33 | } 34 | 35 | .algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { 36 | padding: 0; 37 | background-color: rgb(255,255,255); 38 | border: 0; 39 | max-height: 80vh; 40 | } 41 | 42 | .algolia-autocomplete .ds-dropdown-menu .ds-suggestions { 43 | margin-top: 0 44 | } 45 | 46 | .algolia-autocomplete .algolia-docsearch-suggestion { 47 | padding: 0; 48 | overflow: visible 49 | } 50 | 51 | .algolia-autocomplete .algolia-docsearch-suggestion--category-header { 52 | padding: .125rem 1rem; 53 | margin-top: 0; 54 | font-size: 1.3em; 55 | font-weight: 500; 56 | color: #00008B; 57 | border-bottom: 0 58 | } 59 | 60 | .algolia-autocomplete .algolia-docsearch-suggestion--wrapper { 61 | float: none; 62 | padding-top: 0 63 | } 64 | 65 | .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { 66 | float: none; 67 | width: auto; 68 | padding: 0; 69 | text-align: left 70 | } 71 | 72 | .algolia-autocomplete .algolia-docsearch-suggestion--content { 73 | float: none; 74 | width: auto; 75 | padding: 0 76 | } 77 | 78 | .algolia-autocomplete .algolia-docsearch-suggestion--content::before { 79 | display: none 80 | } 81 | 82 | .algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { 83 | padding-top: .75rem; 84 | margin-top: .75rem; 85 | border-top: 1px solid rgba(0, 0, 0, .1) 86 | } 87 | 88 | .algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { 89 | display: block; 90 | padding: .1rem 1rem; 91 | margin-bottom: 0.1; 92 | font-size: 1.0em; 93 | font-weight: 400 94 | /* display: none */ 95 | } 96 | 97 | .algolia-autocomplete .algolia-docsearch-suggestion--title { 98 | display: block; 99 | padding: .25rem 1rem; 100 | margin-bottom: 0; 101 | font-size: 0.9em; 102 | font-weight: 400 103 | } 104 | 105 | .algolia-autocomplete .algolia-docsearch-suggestion--text { 106 | padding: 0 1rem .5rem; 107 | margin-top: -.25rem; 108 | font-size: 0.8em; 109 | font-weight: 400; 110 | line-height: 1.25 111 | } 112 | 113 | .algolia-autocomplete .algolia-docsearch-footer { 114 | width: 110px; 115 | height: 20px; 116 | z-index: 3; 117 | margin-top: 10.66667px; 118 | float: right; 119 | font-size: 0; 120 | line-height: 0; 121 | } 122 | 123 | .algolia-autocomplete .algolia-docsearch-footer--logo { 124 | background-image: url("data:image/svg+xml;utf8,"); 125 | background-repeat: no-repeat; 126 | background-position: 50%; 127 | background-size: 100%; 128 | overflow: hidden; 129 | text-indent: -9000px; 130 | width: 100%; 131 | height: 100%; 132 | display: block; 133 | transform: translate(-8px); 134 | } 135 | 136 | .algolia-autocomplete .algolia-docsearch-suggestion--highlight { 137 | color: #FF8C00; 138 | background: rgba(232, 189, 54, 0.1) 139 | } 140 | 141 | 142 | .algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { 143 | box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) 144 | } 145 | 146 | .algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { 147 | background-color: rgba(192, 192, 192, .15) 148 | } 149 | -------------------------------------------------------------------------------- /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/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Dot-and-Whisker Plots of Regression Results • dotwhisker 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 24 |
    25 |
    77 | 78 | 79 | 80 | 81 |
    82 |
    83 | 84 |

    85 |

    CRAN version Travis-CI Build Status

    86 |
    87 |
    88 | 90 |

    dotwhisker is an R package for quickly and easily generating dot-and-whisker plots of regression results, either directly from model objects or from tidy data frames. It provides a convenient way to create highly customizable plots for presenting and comparing statistics. It can be used to plot coefficients or other estimates (e.g., predicted probabilities) within a model or compare them across different models. The estimates are presented as dots with confidence interval whiskers, and predictors can be grouped in brackets.

    91 |

    To install:

    92 |
      93 |
    • the latest release version: install.packages("dotwhisker").
    • 94 |
    • the latest development version: if (!require("remotes")) install.packages("remotes"); remotes::install_github("fsolt/dotwhisker").
    • 95 |
    96 |

    More details are available at here:

    97 |

    https://cran.r-project.org/web/packages/dotwhisker/vignettes/dotwhisker-vignette.html

    98 |

    Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

    99 |
    100 | 101 |
    102 | 103 | 142 |
    143 | 144 | 145 |
    149 | 150 |
    151 |

    152 |

    Site built with pkgdown 2.1.1.

    153 |
    154 | 155 |
    156 |
    157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /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: '3.2' 2 | pkgdown: 2.1.1 3 | pkgdown_sha: ~ 4 | articles: 5 | dotwhisker-vignette: dotwhisker-vignette.html 6 | kl2007_examples: kl2007_examples.html 7 | last_built: 2024-09-26T00:43Z 8 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/Rplot002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/Rplot002.png -------------------------------------------------------------------------------- /docs/reference/Rplot003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/Rplot003.png -------------------------------------------------------------------------------- /docs/reference/Rplot004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/Rplot004.png -------------------------------------------------------------------------------- /docs/reference/Rplot005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/Rplot005.png -------------------------------------------------------------------------------- /docs/reference/add_brackets-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/add_brackets-1.png -------------------------------------------------------------------------------- /docs/reference/by_2sd.html: -------------------------------------------------------------------------------- 1 | 2 | Rescale regression results by multiplying by 2 standard deviations — by_2sd • dotwhisker 6 | 7 | 8 |
    9 |
    53 | 54 | 55 | 56 |
    57 |
    58 | 63 | 64 |
    65 |

    by_2sd rescales regression results to facilitate making dot-and-whisker plots using dwplot.

    66 |
    67 | 68 |
    69 |
    by_2sd(df, dataset)
    70 |
    71 | 72 |
    73 |

    Arguments

    74 | 75 | 76 |
    df
    77 |

    A data frame including the variables term (names of independent variables), estimate (corresponding coefficient estimates), std.error (corresponding standard errors), and optionally model (when multiple models are desired on a single plot) such as generated those by tidy.

    78 | 79 | 80 |
    dataset
    81 |

    The data analyzed in the models whose results are recorded in df, or (preferably) the model matrix used by the models in df; the information required for complex models can more easily be generated from the model matrix than from the original data set. In many cases the model matrix can be extracted from the original model via model.matrix.

    82 | 83 |
    84 |
    85 |

    Value

    86 |

    A tidy data frame

    87 |
    88 |
    89 |

    Details

    90 |

    by_2sd multiplies the results from regression models saved as tidy data frames for predictors that are not binary by twice the standard deviation of these variables in the dataset analyzed. Standardizing in this way yields coefficients that are directly comparable to each other and to those for untransformed binary predictors (Gelman 2008) and so facilitates plotting using dwplot. Note that the current version of by_2sd does not subtract the mean (in contrast to Gelman's (2008) formula). However, all estimates and standard errors of the independent variables are the same as if the mean was subtracted. The only difference from Gelman (2008) is that for all variables in the model the intercept is shifted by the coefficient times the mean of the variable.

    91 |

    An alternative available in some circumstances is to pass a model object to arm::standardize before passing the results to tidy and then on to dwplot. The advantages of by_2sd are that (1) it takes a tidy data frame as its input and so is not restricted to only those model objects that standardize accepts and (2) it is much more efficient because it operates on the parameters rather than refitting the original model with scaled data.

    92 |
    93 |
    94 |

    References

    95 |

    Gelman, Andrew. 2008. "Scaling Regression Inputs by Dividing by Two Standard Deviations." Statistics in Medicine, 27:2865-2873.

    96 |
    97 | 98 |
    99 |

    Examples

    100 |
    library(broom)
    101 | library(dplyr)
    102 | 
    103 | data(mtcars)
    104 | m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars)
    105 | m1_df <- tidy(m1) %>% by_2sd(mtcars) # create data frame of rescaled regression results
    106 | 
    107 | 
    108 |
    109 |
    110 | 113 |
    114 | 115 | 116 |
    119 | 120 |
    121 |

    Site built with pkgdown 2.1.1.

    122 |
    123 | 124 |
    125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/reference/dwplot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/dwplot-1.png -------------------------------------------------------------------------------- /docs/reference/dwplot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/dwplot-2.png -------------------------------------------------------------------------------- /docs/reference/dwplot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/dwplot-3.png -------------------------------------------------------------------------------- /docs/reference/dwplot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/dwplot-4.png -------------------------------------------------------------------------------- /docs/reference/dwplot-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/dwplot-5.png -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | Package index • dotwhisker 6 | 7 | 8 |
    9 |
    53 | 54 | 55 | 56 |
    57 |
    58 | 61 | 62 | 66 | 69 | 70 | 73 | 74 | 77 | 78 | 81 | 82 | 85 | 86 | 89 | 90 | 93 | 94 |
    63 |

    All functions

    64 |

    65 |
    67 |

    add_brackets()

    68 |

    Add Labelled Brackets to Group Predictors in a Dot-and-Whisker Plot

    71 |

    by_2sd()

    72 |

    Rescale regression results by multiplying by 2 standard deviations

    75 |

    dwplot() dw_plot()

    76 |

    Dot-and-Whisker Plots of Regression Results

    79 |

    relabel_predictors()

    80 |

    Relabel the Predictors in a Tidy Data Frame of Regression Results

    83 |

    relabel_y_axis()

    84 |

    Relabel the Y-Axis of a Dot-Whisker Plot

    87 |

    secret_weapon()

    88 |

    Generate a 'Secret Weapon' Plot of Regression Results from Multiple Models

    91 |

    small_multiple()

    92 |

    Generate a 'Small Multiple' Plot of Regression Results

    95 | 96 | 99 |
    100 | 101 | 102 |
    105 | 106 |
    107 |

    Site built with pkgdown 2.1.1.

    108 |
    109 | 110 |
    111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /docs/reference/relabel_predictors-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/relabel_predictors-1.png -------------------------------------------------------------------------------- /docs/reference/relabel_predictors-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/relabel_predictors-2.png -------------------------------------------------------------------------------- /docs/reference/relabel_y_axis.html: -------------------------------------------------------------------------------- 1 | 2 | Relabel the Y-Axis of a Dot-Whisker Plot — relabel_y_axis • dotwhisker 6 | 7 | 8 |
    9 |
    53 | 54 | 55 | 56 |
    57 |
    58 | 63 | 64 |
    65 |

    relabel_y_axis DEPRECATED. A convenience function for relabeling the predictors on the y-axis of a dot-whisker plot created by dwplot. It is deprecated; use relabel_predictors instead.

    66 |
    67 | 68 |
    69 |
    relabel_y_axis(x)
    70 |
    71 | 72 |
    73 |

    Arguments

    74 | 75 | 76 |
    x
    77 |

    A vector of labels for predictors, listed from top to bottom

    78 | 79 |
    80 |
    81 |

    Value

    82 |

    The function returns an object of the same type as it is passed: a plot generated by dwplot.

    83 |
    84 |
    85 |

    See also

    86 |

    relabel_predictors to relabel predictors on the y-axis of a dot-whisker plot or in a tidy data.frame

    87 |
    88 | 89 |
    90 | 93 |
    94 | 95 | 96 |
    99 | 100 |
    101 |

    Site built with pkgdown 2.1.1.

    102 |
    103 | 104 |
    105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/reference/secret_weapon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/secret_weapon-1.png -------------------------------------------------------------------------------- /docs/reference/small_multiple-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/small_multiple-1.png -------------------------------------------------------------------------------- /docs/reference/small_multiple-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fsolt/dotwhisker/6444a03d6113ae668cf6f0502c45a54028f4a2e2/docs/reference/small_multiple-2.png -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | /404.html 3 | /articles/dotwhisker-vignette.html 4 | /articles/index.html 5 | /articles/kl2007_examples.html 6 | /authors.html 7 | /CONDUCT.html 8 | /index.html 9 | /LICENSE-text.html 10 | /news/index.html 11 | /reference/add_brackets.html 12 | /reference/by_2sd.html 13 | /reference/dwplot.html 14 | /reference/index.html 15 | /reference/relabel_predictors.html 16 | /reference/relabel_y_axis.html 17 | /reference/secret_weapon.html 18 | /reference/small_multiple.html 19 | 20 | 21 | -------------------------------------------------------------------------------- /dotwhisker.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 4 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageCheckArgs: --as-cran 22 | PackageRoxygenize: rd,collate,namespace,vignette 23 | -------------------------------------------------------------------------------- /man/add_brackets.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/add_brackets.R 3 | \name{add_brackets} 4 | \alias{add_brackets} 5 | \title{Add Labelled Brackets to Group Predictors in a Dot-and-Whisker Plot} 6 | \usage{ 7 | add_brackets(p, brackets, fontSize = 0.7, face = "italic", ...) 8 | } 9 | \arguments{ 10 | \item{p}{A plot generated by \code{dwplot}. Any `ggplot` customization should be done before passing the plot to \code{add_brackets}. To pass the finalized plot to \code{add_brackets} without creating an intermediate object, simply wrap the code that generates it in braces (\code{`{`} and \code{`}`}).} 11 | 12 | \item{brackets}{A list of brackets; each element of the list should be a character vector consisting of (1) a label for the bracket, (2) the name of the topmost variable to be enclosed by the bracket, and (3) the name of the bottom most variable to be enclosed by the bracket.} 13 | 14 | \item{fontSize}{A number defining the size of the bracket label. The default value is .7.} 15 | 16 | \item{face}{A typeface for the bracket labels; options are "plain", "bold", "italic", "oblique", and "bold.italic".} 17 | 18 | \item{\dots}{Extra arguments to pass to \code{\link[grid]{gpar}}.} 19 | } 20 | \value{ 21 | The function returns a \code{ggplot} object. 22 | } 23 | \description{ 24 | \code{add_brackets} draws brackets along the y-axis beyond the plotting area of a dot-and-whisker plot generated by \code{dwplot}, useful for labelling groups of predictors 25 | } 26 | \details{ 27 | The brackets are drawn by `grid` functions. Apart from font size and typeface, users can customize the appearance of the bracket labels by setting `gpar` arguments in `add_brackets`. 28 | } 29 | \examples{ 30 | library(dplyr) 31 | m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars) 32 | two_brackets <- list(c("Engine", "Cylinder", "Displacement"), 33 | c("Not Engine", "Intercept", "Weight")) 34 | 35 | {dwplot(m1, show_intercept = TRUE) \%>\% 36 | relabel_predictors("(Intercept)" = "Intercept", 37 | wt = "Weight", 38 | cyl = "Cylinder", 39 | disp = "Displacement") + 40 | theme_bw() + xlab("Coefficient") + ylab("") + 41 | theme(legend.position="none") + 42 | geom_vline(xintercept = 0, colour = "grey50", linetype = 2)} \%>\% 43 | add_brackets(two_brackets) 44 | 45 | } 46 | -------------------------------------------------------------------------------- /man/by_2sd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/by_2sd.R 3 | \name{by_2sd} 4 | \alias{by_2sd} 5 | \title{Rescale regression results by multiplying by 2 standard deviations} 6 | \usage{ 7 | by_2sd(df, dataset) 8 | } 9 | \arguments{ 10 | \item{df}{A data frame including the variables \code{term} (names of independent variables), \code{estimate} (corresponding coefficient estimates), \code{std.error} (corresponding standard errors), and optionally \code{model} (when multiple models are desired on a single plot) such as generated those by \code{\link[broom]{tidy}}.} 11 | 12 | \item{dataset}{The data analyzed in the models whose results are recorded in \code{df}, or (preferably) the \emph{model matrix} used by the models in \code{df}; the information required for complex models can more easily be generated from the model matrix than from the original data set. In many cases the model matrix can be extracted from the original model via \code{\link{model.matrix}}.} 13 | } 14 | \value{ 15 | A tidy data frame 16 | } 17 | \description{ 18 | \code{by_2sd} rescales regression results to facilitate making dot-and-whisker plots using \code{\link[dotwhisker]{dwplot}}. 19 | } 20 | \details{ 21 | \code{by_2sd} multiplies the results from regression models saved as tidy data frames for predictors that are not binary by twice the standard deviation of these variables in the dataset analyzed. Standardizing in this way yields coefficients that are directly comparable to each other and to those for untransformed binary predictors (Gelman 2008) and so facilitates plotting using \code{\link[dotwhisker]{dwplot}}. Note that the current version of \code{by_2sd} does not subtract the mean (in contrast to Gelman's (2008) formula). However, all estimates and standard errors of the independent variables are the same as if the mean was subtracted. The only difference from Gelman (2008) is that for all variables in the model the intercept is shifted by the coefficient times the mean of the variable. 22 | 23 | An alternative available in some circumstances is to pass a model object to \code{arm::standardize} before passing the results to \code{\link[broom]{tidy}} and then on to \code{\link[dotwhisker]{dwplot}}. The advantages of \code{by_2sd} are that (1) it takes a tidy data frame as its input and so is not restricted to only those model objects that \code{standardize} accepts and (2) it is much more efficient because it operates on the parameters rather than refitting the original model with scaled data. 24 | } 25 | \examples{ 26 | library(broom) 27 | library(dplyr) 28 | 29 | data(mtcars) 30 | m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars) 31 | m1_df <- tidy(m1) \%>\% by_2sd(mtcars) # create data frame of rescaled regression results 32 | 33 | } 34 | \references{ 35 | Gelman, Andrew. 2008. "Scaling Regression Inputs by Dividing by Two Standard Deviations." Statistics in Medicine, 27:2865-2873. 36 | } 37 | -------------------------------------------------------------------------------- /man/dwplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dwplot.R 3 | \name{dwplot} 4 | \alias{dwplot} 5 | \alias{dw_plot} 6 | \title{Dot-and-Whisker Plots of Regression Results} 7 | \usage{ 8 | dwplot( 9 | x, 10 | ci = 0.95, 11 | dodge_size = 0.4, 12 | vars_order = NULL, 13 | show_intercept = FALSE, 14 | show_stats = FALSE, 15 | stats_tb = NULL, 16 | stats_digits = 3, 17 | stats_compare = FALSE, 18 | stats_verbose = FALSE, 19 | stats_size = 10, 20 | stats_padding = unit(c(4, 4), "mm"), 21 | stats_layout = c(2, -1, 1), 22 | margins = FALSE, 23 | model_name = "model", 24 | model_order = NULL, 25 | style = c("dotwhisker", "distribution"), 26 | by_2sd = FALSE, 27 | vline = NULL, 28 | dot_args = list(size = 1.2), 29 | whisker_args = list(size = 0.5), 30 | dist_args = list(alpha = 0.5), 31 | line_args = list(alpha = 0.75, size = 1), 32 | ... 33 | ) 34 | 35 | dw_plot( 36 | x, 37 | ci = 0.95, 38 | dodge_size = 0.4, 39 | vars_order = NULL, 40 | show_intercept = FALSE, 41 | show_stats = FALSE, 42 | stats_tb = NULL, 43 | stats_digits = 3, 44 | stats_compare = FALSE, 45 | stats_verbose = FALSE, 46 | stats_size = 10, 47 | stats_padding = unit(c(4, 4), "mm"), 48 | stats_layout = c(2, -1, 1), 49 | margins = FALSE, 50 | model_name = "model", 51 | model_order = NULL, 52 | style = c("dotwhisker", "distribution"), 53 | by_2sd = FALSE, 54 | vline = NULL, 55 | dot_args = list(size = 1.2), 56 | whisker_args = list(size = 0.5), 57 | dist_args = list(alpha = 0.5), 58 | line_args = list(alpha = 0.75, size = 1), 59 | ... 60 | ) 61 | } 62 | \arguments{ 63 | \item{x}{Either a model object to be tidied with \code{\link[broom]{tidy}}, or a list of such model objects, or a tidy data frame of regression results (see 'Details').} 64 | 65 | \item{ci}{A number indicating the level of confidence intervals; the default is .95.} 66 | 67 | \item{dodge_size}{A number indicating how much vertical separation should be between different models' coefficients when multiple models are graphed in a single plot. Lower values tend to look better when the number of independent variables is small, while a higher value may be helpful when many models appear on the same plot; the default is 0.4.} 68 | 69 | \item{vars_order}{A vector of variable names that specifies the order in which the variables are to appear along the y-axis of the plot. Note that the order will be overwritten by \code{\link[dotwhisker]{relabel_predictors}}, if the function is following called.} 70 | 71 | \item{show_intercept}{A logical constant indicating whether the coefficient of the intercept term should be plotted. The default is \code{FALSE}.} 72 | 73 | \item{show_stats}{A logical constant indicating whether to show a table of model fitness statistics under the dot-whisker plot. The default is \code{TRUE}.} 74 | 75 | \item{stats_tb}{Customized table of model fit. The table should be in a \code{data.frame}.} 76 | 77 | \item{stats_digits}{A numeric value specifying the digits to display in the fitness table. This parameter is relevant only when \code{show_stats = TRUE}. Default is 3, providing a balance between precision and readability.} 78 | 79 | \item{stats_compare}{A logical constant to enable comparison of statistics in the fitness table. Applicable only when \code{show_stats = TRUE}. The default value is \code{FALSE}. That is, it presents all the statistics across different modeling methods, yet potentially expanding the table's breadth. When set to \code{TRUE}, only the shared, comparable statistics are remained.} 80 | 81 | \item{stats_verbose}{A logical constant to turn on/off the toggle warnings and messages of model fits. The default is \code{FALSE}.} 82 | 83 | \item{stats_size}{A numeric value determining the font size in the fitness table, effective only if \code{show_stats = TRUE}. The standard setting is 10.} 84 | 85 | \item{stats_padding}{Defining the internal margins of the fitness table. Relevant when \code{show_stats = TRUE}. Set by default to \code{unit(c(4, 4), "mm")}, allowing for a balanced layout. Further customization options refer to \code{\link[gridExtra]{tableGrob}}.} 86 | 87 | \item{stats_layout}{Adjusting the spacing between the dotwhisker plot and the fitness table. Effective when \code{show_stats = TRUE}. The initial configuration is \code{c(2, -1, 1)}, ensuring a coherent visual flow. Additional layout settings refer to \code{\link[patchwork]{plot_layout}}.} 88 | 89 | \item{margins}{A logical value indicating whether presenting the average marginal effects of the estimates. See the Details for more information.} 90 | 91 | \item{model_name}{The name of a variable that distinguishes separate models within a tidy data frame.} 92 | 93 | \item{model_order}{A character vector defining the order of the models when multiple models are involved.} 94 | 95 | \item{style}{Either \code{"dotwhisker"} or \code{"distribution"}. \code{"dotwhisker"}, the default, shows the regression coefficients' point estimates as dots with confidence interval whiskers. \code{"distribution"} shows the normal distribution with mean equal to the point estimate and standard deviation equal to the standard error, underscored with a confidence interval whisker.} 96 | 97 | \item{by_2sd}{When x is model object or list of model objects, should the coefficients for predictors that are not binary be rescaled by twice the standard deviation of these variables in the dataset analyzed, per Gelman (2008)? Defaults to \code{FALSE}. Note that when x is a tidy data frame, one can use \code{\link[dotwhisker]{by_2sd}} to rescale similarly.} 98 | 99 | \item{vline}{A \code{geom_vline()} object, typically with \code{xintercept = 0}, to be drawn behind the coefficients.} 100 | 101 | \item{dot_args}{When \code{style} is "dotwhisker", a list of arguments specifying the appearance of the dots representing mean estimates. For supported arguments, see \code{\link[ggplot2]{geom_point}}.} 102 | 103 | \item{whisker_args}{When \code{style} is "dotwhisker", a list of arguments specifying the appearance of the whiskers representing the confidence intervals. For supported arguments, see \code{\link[ggstance]{geom_linerangeh}}.} 104 | 105 | \item{dist_args}{When \code{style} is "distribution", a list of arguments specifying the appearance of normally distributed regression estimates. For supported arguments, see \code{\link[ggplot2]{geom_polygon}}.} 106 | 107 | \item{line_args}{When \code{style} is "distribution", a list of arguments specifying the appearance of the line marking the confidence interval beneath the normal distribution. For supported arguments, see \code{\link[ggstance]{geom_linerangeh}}.} 108 | 109 | \item{\dots}{Extra arguments to pass to \code{\link[parameters]{parameters}}.} 110 | } 111 | \value{ 112 | The function returns a \code{ggplot} object. 113 | } 114 | \description{ 115 | \code{dwplot} is a function for quickly and easily generating dot-and-whisker plots of regression models saved in tidy data frames. 116 | } 117 | \details{ 118 | \code{dwplot} visualizes regression model objects or regression results saved in tidy data frames as dot-and-whisker plots generated by \code{\link[ggplot2]{ggplot}}. 119 | 120 | Tidy data frames to be plotted should include the variables \code{term} (names of predictors), \code{estimate} (corresponding estimates of coefficients or other quantities of interest), \code{std.error} (corresponding standard errors), and optionally \code{model} (when multiple models are desired on a single plot; a different name for this last variable may be specified using the model_name argument). 121 | In place of \code{std.error} one may substitute \code{conf.low} (the lower bounds of the confidence intervals of each estimate) and \code{conf.high} (the corresponding upper bounds). 122 | 123 | For convenience, \code{dwplot} also accepts as input those model objects that can be tidied by \code{\link[broom]{tidy}} (or \code{\link[parameters]{parameters}} (with proper formatting)), or a list of such model objects. 124 | 125 | By default, the plot will display 95-percent confidence intervals. To display a different interval when passing a model object or objects, specify a \code{ci} argument. When passing a data frame of results, include the variables \code{conf.low} and \code{conf.high} describing the bounds of the desired interval. 126 | 127 | Because the function can take a data frame as input, it is easily employed for a wide range of models, including those not supported by \code{broom} or \code{parameters}. 128 | And because the output is a \code{ggplot} object, it can easily be further customized with any additional arguments and layers supported by \code{ggplot2}. 129 | Together, these two features make \code{dwplot} extremely flexible. 130 | 131 | \code{dwplot} provides an option to present the average marginal effect directly. Users can alter the confidence intervals of the margins through the \code{ci} argument. The `margins` argument also works for \code{small_multiple} and \code{secret_weapon}. Note that for models with categorical outcome variables (such as ordered logit or multinomial regression), each category (level) has its own average marignal effects. To maintain visualization consistency with models with continuous or binary outcomes, \code{dwplot} only displays marginal effects for the first category. 132 | 133 | To minimize the need for lengthy, distracting regression tables (often relegated to an appendix for dot-whisker plot users), \code{dwplot} incorporates optimal model fit statistics directly beneath the dot-whisker plots. These statistics are derived using the excellent \code{\link[performance]{performance}} functions and integrated at the plot's base via \code{\link[patchwork]{patchwork}} and \code{\link[gridExtra]{tableGrob}} functions. For added flexibility, \code{dwplot} includes the \code{stats_tb} feature, allowing users to input customized statistics. Furthermore, a suite of \code{stats_*} functions is available for fine-tuning the presentation of these statistics, enhancing user control over the visual output. 134 | } 135 | \examples{ 136 | library(dplyr) 137 | # Plot regression coefficients from a single model object 138 | data(mtcars) 139 | m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars) 140 | dwplot(m1, vline = geom_vline(xintercept = 0, colour = "grey50", linetype = 2)) + 141 | xlab("Coefficient") 142 | # using 99\% confidence interval 143 | dwplot(m1, ci = .99) 144 | # Plot regression coefficients from multiple models 145 | m2 <- update(m1, . ~ . - disp) 146 | dwplot(list(full = m1, nodisp = m2)) 147 | # Change the appearance of dots and whiskers 148 | dwplot(m1, dot_args = list(size = 3, pch = 21, fill = "white")) 149 | # Plot regression coefficients from multiple models on the fly 150 | mtcars \%>\% 151 | split(.$am) \%>\% 152 | purrr::map(~ lm(mpg ~ wt + cyl + disp, data = .x)) \%>\% 153 | dwplot() \%>\% 154 | relabel_predictors(c(wt = "Weight", cyl = "Cylinders", disp = "Displacement")) + 155 | theme_bw() + xlab("Coefficient") + ylab("") + 156 | geom_vline(xintercept = 0, colour = "grey60", linetype = 2) + 157 | ggtitle("Predicting Gas Mileage, OLS Estimates") + 158 | theme(plot.title = element_text(face = "bold"), 159 | legend.position = c(.995, .99), 160 | legend.justification = c(1, 1), 161 | legend.background = element_rect(colour="grey80"), 162 | legend.title.align = .5) + 163 | scale_colour_grey(start = .4, end = .8, 164 | name = "Transmission", 165 | breaks = c("Model 0", "Model 1"), 166 | labels = c("Automatic", "Manual")) 167 | 168 | } 169 | \references{ 170 | Kastellec, Jonathan P. and Leoni, Eduardo L. 2007. "Using Graphs Instead of Tables in Political Science." *Perspectives on Politics*, 5(4):755-771. 171 | 172 | Gelman, Andrew. 2008. "Scaling Regression Inputs by Dividing by Two Standard Deviations." *Statistics in Medicine*, 27:2865-2873. 173 | } 174 | -------------------------------------------------------------------------------- /man/relabel_predictors.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/relabel_predictors.R 3 | \name{relabel_predictors} 4 | \alias{relabel_predictors} 5 | \title{Relabel the Predictors in a Tidy Data Frame of Regression Results} 6 | \usage{ 7 | relabel_predictors(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Either a tidy data frame to be passed to \code{\link[dotwhisker]{dwplot}} or a plot generated by \code{\link[dotwhisker]{dwplot}}.} 11 | 12 | \item{...}{Named replacements, as in \code{\link[dplyr]{recode}}. The argument names should be the current values to be replaced, and the argument values should be the new (replacement) values. For backwards compatibility, a named character vector, with new values as values, and old values as names may also be used. The order of the named replacements will be preserved, so this function also serves the purpose of reordering variables.} 13 | } 14 | \value{ 15 | The function returns an object of the same type as it is passed: a tidy data frame or a plot generated by \code{\link[dotwhisker]{dwplot}}. 16 | } 17 | \description{ 18 | \code{relabel_predictors} is a convenience function for relabeling the predictors in a tidy data frame to be passed to \code{\link[dotwhisker]{dwplot}} or a plot generated by \code{\link[dotwhisker]{dwplot}} 19 | } 20 | \examples{ 21 | library(broom) 22 | library(dplyr) 23 | 24 | data(mtcars) 25 | m1 <- lm(mpg ~ wt + cyl + disp, data = mtcars) 26 | m1_df <- broom::tidy(m1) \%>\% 27 | relabel_predictors("(Intercept)" = "Intercept", 28 | wt = "Weight", 29 | disp = "Displacement", 30 | cyl = "Cylinder") 31 | dwplot(m1_df) 32 | 33 | dwplot(m1, show_intercept = TRUE) \%>\% 34 | relabel_predictors("(Intercept)" = "Intercept", 35 | wt = "Weight", 36 | disp = "Displacement", 37 | cyl = "Cylinder") 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /man/relabel_y_axis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/relabel_y_axis.R 3 | \name{relabel_y_axis} 4 | \alias{relabel_y_axis} 5 | \title{Relabel the Y-Axis of a Dot-Whisker Plot} 6 | \usage{ 7 | relabel_y_axis(x) 8 | } 9 | \arguments{ 10 | \item{x}{A vector of labels for predictors, listed from top to bottom} 11 | } 12 | \value{ 13 | The function returns an object of the same type as it is passed: a plot generated by \code{\link[dotwhisker]{dwplot}}. 14 | } 15 | \description{ 16 | \code{relabel_y_axis} DEPRECATED. A convenience function for relabeling the predictors on the y-axis of a dot-whisker plot created by \code{\link[dotwhisker]{dwplot}}. It is deprecated; use \code{\link[dotwhisker]{relabel_predictors}} instead. 17 | } 18 | \seealso{ 19 | \code{\link[dotwhisker]{relabel_predictors}} to relabel predictors on the y-axis of a dot-whisker plot or in a tidy data.frame 20 | } 21 | -------------------------------------------------------------------------------- /man/secret_weapon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/secret_weapon.R 3 | \name{secret_weapon} 4 | \alias{secret_weapon} 5 | \title{Generate a 'Secret Weapon' Plot of Regression Results from Multiple Models} 6 | \usage{ 7 | secret_weapon(x, var = NULL, ci = 0.95, margins = FALSE, by_2sd = FALSE, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Either a model object to be tidied with \code{\link[broom]{tidy}}, or a list of such model objects, or a tidy data frame of regression results (see 'Details').} 11 | 12 | \item{var}{The predictor whose results are to be shown in the 'secret weapon' plot} 13 | 14 | \item{ci}{A number indicating the level of confidence intervals; the default is .95.} 15 | 16 | \item{margins}{A logical value indicating whether presenting the average marginal effects of the estimates. See the Details of \code{dwplot} for more information.} 17 | 18 | \item{by_2sd}{When x is a list of model objects, should the coefficients for predictors that are not binary be rescaled by twice the standard deviation of these variables in the dataset analyzed, per Gelman (2008)? Defaults to \code{TRUE}. Note that when x is a tidy data frame, one can use \code{\link[dotwhisker]{by_2sd}} to rescale similarly.} 19 | 20 | \item{\dots}{Arguments to pass to \code{\link[dotwhisker]{dwplot}}.} 21 | } 22 | \value{ 23 | The function returns a \code{ggplot} object. 24 | } 25 | \description{ 26 | \code{secret_weapon} is a function for plotting regression results of multiple models as a 'secret weapon' plot 27 | } 28 | \details{ 29 | Andrew Gelman has coined the term "the secret weapon" for dot-and-whisker plots that compare the estimated coefficients for a single predictor across many models or datasets. 30 | \code{secret_weapon} takes a tidy data frame of regression results or a list of model objects and generates a dot-and-whisker plot of the results of a single variable across the multiple models. 31 | 32 | Tidy data frames to be plotted should include the variables \code{term} (names of predictors), \code{estimate} (corresponding estimates of coefficients or other quantities of interest), \code{std.error} (corresponding standard errors), and \code{model} (identifying the corresponding model). 33 | In place of \code{std.error} one may substitute \code{lb} (the lower bounds of the confidence intervals of each estimate) and \code{ub} (the corresponding upper bounds). 34 | 35 | Alternately, \code{secret_weapon} accepts as input a list of model objects that can be tidied by \code{\link[broom]{tidy}} (or \code{\link[parameters]{parameters}} (with proper formatting)), or a list of such model objects. 36 | } 37 | \examples{ 38 | 39 | library(dplyr) 40 | library(broom) 41 | 42 | # Estimate models across many samples, put results in a tidy data frame 43 | by_clarity <- diamonds \%>\% group_by(clarity) \%>\% 44 | do(tidy(lm(price ~ carat + cut + color, data = .))) \%>\% 45 | ungroup \%>\% rename(model = clarity) 46 | 47 | # Generate a 'secret weapon' plot of the results of diamond size 48 | secret_weapon(by_clarity, "carat") 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /man/small_multiple.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/small_multiple.R 3 | \name{small_multiple} 4 | \alias{small_multiple} 5 | \title{Generate a 'Small Multiple' Plot of Regression Results} 6 | \usage{ 7 | small_multiple( 8 | x, 9 | ci = 0.95, 10 | margins = FALSE, 11 | dodge_size = 0.4, 12 | show_intercept = FALSE, 13 | show_stats = FALSE, 14 | stats_tb = NULL, 15 | stats_digits = 3, 16 | stats_compare = FALSE, 17 | stats_verbose = FALSE, 18 | stats_size = 10, 19 | stats_padding = unit(c(4, 4), "mm"), 20 | stats_layout = c(2, -1, 1), 21 | model_order = NULL, 22 | submodel_order = NULL, 23 | axis_switch = FALSE, 24 | by_2sd = FALSE, 25 | dot_args = list(size = 0.3), 26 | ... 27 | ) 28 | } 29 | \arguments{ 30 | \item{x}{Either a model object to be tidied with \code{\link[broom]{tidy}}, or a list of such model objects, or a tidy data frame of regression results (see 'Details').} 31 | 32 | \item{ci}{A number indicating the level of confidence intervals; the default is .95.} 33 | 34 | \item{margins}{A logical value indicating whether presenting the average marginal effects of the estimates. See the Details of \code{dwplot} for more information.} 35 | 36 | \item{dodge_size}{A number (typically between 0 and 0.3; the default is .06) indicating how much horizontal separation should appear between different submodels' coefficients when multiple submodels are graphed in a single plot. Lower values tend to look better when the number of models is small, while a higher value may be helpful when many submodels appear on the same plot.} 37 | 38 | \item{show_intercept}{A logical constant indicating whether the coefficient of the intercept term should be plotted.} 39 | 40 | \item{show_stats}{A logical constant indicating whether to show a table of model fitness statistics under the dot-whisker plot. The default is \code{TRUE}.} 41 | 42 | \item{stats_tb}{Customized table of model fitness. The table should be in a \code{data.frame}.} 43 | 44 | \item{stats_digits}{A numeric value specifying the digits to display in the fitness table. This parameter is relevant only when \code{show_stats = TRUE}. Default is 3, providing a balance between precision and readability.} 45 | 46 | \item{stats_compare}{A logical constant to enable comparison of statistics in the fitness table. Applicable only when \code{show_stats = TRUE}. The default value is \code{FALSE}. That is, it presents all the statistics across different modeling methods, yet potentially expanding the table's breadth. When set to \code{TRUE}, only the shared, comparable statistics are remained.} 47 | 48 | \item{stats_verbose}{A logical constant to turn on/off the toggle warnings and messages of model fits. The default is \code{FALSE}.} 49 | 50 | \item{stats_size}{A numeric value determining the font size in the fitness table, effective only if \code{show_stats = TRUE}. The standard setting is 10.} 51 | 52 | \item{stats_padding}{Defining the internal margins of the fitness table. Relevant when \code{show_stats = TRUE}. Set by default to \code{unit(c(4, 4), "mm")}, allowing for a balanced layout. Further customization options refer to \code{\link[gridExtra]{tableGrob}}.} 53 | 54 | \item{stats_layout}{Adjusting the spacing between the dotwhisker plot and the fitness table. Effective when \code{show_stats = TRUE}. The initial configuration is \code{c(2, -1, 1)}, ensuring a coherent visual flow. Additional layout settings refer to \code{\link[patchwork]{plot_layout}}.} 55 | 56 | \item{model_order}{A character vector defining the order of the models when multiple models are involved.} 57 | 58 | \item{submodel_order}{A character vector defining the order of the submodels when multiple submodels are involved.} 59 | 60 | \item{axis_switch}{A logical constant indicating the position of variable labels and y axis ticks. Default is FALSE, when the variable label is on the right side, and y axis ticks is on the left size.} 61 | 62 | \item{by_2sd}{When x is model object or list of model objects, should the coefficients for predictors that are not binary be rescaled by twice the standard deviation of these variables in the dataset analyzed, per Gelman (2008)? Defaults to \code{TRUE}. Note that when x is a tidy data frame, one can use \code{\link[dotwhisker]{by_2sd}} to rescale similarly.} 63 | 64 | \item{dot_args}{A list of arguments specifying the appearance of the dots representing mean estimates. For supported arguments, see \code{\link[ggstance]{geom_pointrangeh}}.} 65 | 66 | \item{\dots}{Arguments to pass to \code{\link[dotwhisker]{dwplot}}.} 67 | } 68 | \value{ 69 | The function returns a \code{ggplot} object. 70 | } 71 | \description{ 72 | \code{small_multiple} is a function for plotting regression results of multiple models as a 'small multiple' plot 73 | } 74 | \details{ 75 | \code{small_multiple}, following \href{https://www.cambridge.org/core/journals/perspectives-on-politics/article/using-graphs-instead-of-tables-in-political-science/9FD63E9EE686AF046732191EE8A68034}{Kastellec and Leoni (2007)}, provides a compact means of representing numerous regression models in a single plot. 76 | 77 | Tidy data frames to be plotted should include the variables \code{term} (names of predictors), \code{estimate} (corresponding estimates of coefficients or other quantities of interest), \code{std.error} (corresponding standard errors), and \code{model} (identifying the corresponding model). 78 | In place of \code{std.error} one may substitute \code{conf.low} (the lower bounds of the confidence intervals of each estimate) and \code{conf.high} (the corresponding upper bounds). 79 | 80 | Alternately, \code{small_multiple} accepts as input a list of model objects that can be tidied by \code{\link[broom]{tidy}} (or \code{\link[parameters]{parameters}} (with proper formatting)), or a list of such model objects. 81 | 82 | Optionally, more than one set of results can be clustered to facilitate comparison within each \code{model}; one example of when this may be desirable is to compare results across samples. In that case, the data frame should also include a variable \code{submodel} identifying the submodel of the results. 83 | 84 | To minimize the need for lengthy, distracting regression tables (often relegated to an appendix for dot-whisker plot users), \code{dwplot} incorporates optimal model fit statistics directly beneath the dot-whisker plots. These statistics are derived using the excellent \code{\link[performance]{performance}} functions and integrated at the plot's base via \code{\link[patchwork]{patchwork}} and \code{\link[gridExtra]{tableGrob}} functions. For added flexibility, \code{dwplot} includes the \code{stats_tb} feature, allowing users to input customized statistics. Furthermore, a suite of \code{stats_*} functions is available for fine-tuning the presentation of these statistics, enhancing user control over the visual output. 85 | } 86 | \examples{ 87 | 88 | m1 <- lm(mpg ~ wt + cyl + disp + gear, data = mtcars) 89 | m2 <- update(m1, . ~ . + hp) 90 | 91 | 92 | # Generate a 'small multiple' plot 93 | small_multiple(list(m1, m2)) 94 | } 95 | \references{ 96 | Kastellec, Jonathan P. and Leoni, Eduardo L. 2007. "Using Graphs Instead of Tables in Political Science." *Perspectives on Politics*, 5(4):755-771. 97 | } 98 | -------------------------------------------------------------------------------- /vignettes/vignette.bib: -------------------------------------------------------------------------------- 1 | % Encoding: UTF-8 2 | 3 | @Article{Kastellec2007, 4 | Title = {Using Graphs Instead of Tables in Political Science}, 5 | Author = {Kastellec, Jonathan P. and Leoni, Eduardo L.}, 6 | Journal = {Perspectives on Politics}, 7 | Year = {2007}, 8 | Number = {4}, 9 | Pages = {755--771}, 10 | Volume = {5}, 11 | } 12 | 13 | @Article{Gelman2008, 14 | Title = {Scaling Regression Inputs by Dividing by Two Standard Deviations}, 15 | Author = {Gelman, Andrew}, 16 | Journal = {Statistics in medicine}, 17 | Year = {2008}, 18 | Number = {15}, 19 | Pages = {2865--2873}, 20 | Volume = {27} 21 | } 22 | 23 | @Article{Gelman2002, 24 | title={Let's Practice What We Preach: Turning Tables into Graphs}, 25 | author={Gelman, Andrew and Pasarica, Cristian and Dodhia, Rahul}, 26 | journal={American Statistician}, 27 | volume={56}, 28 | number={2}, 29 | pages={121--130}, 30 | year={2002} 31 | } 32 | 33 | @Book{Wickham2009, 34 | title = {{ggplot2}: Elegant Graphics for Data Analysis}, 35 | publisher = {Springer}, 36 | year = {2009}, 37 | author = {Hadley Wickham}, 38 | address = {New York}, 39 | isbn = {978-0-387-98140-6}, 40 | url = {https://ggplot2-book.org/} 41 | } 42 | 43 | @Manual{Robinson2015, 44 | title = {{broom}: Convert Statistical Analysis Objects into Tidy Data Frames}, 45 | author = {David Robinson}, 46 | year = {2015}, 47 | note = {R package version 0.3.7}, 48 | url = {https://CRAN.R-project.org/package=broom} 49 | } 50 | 51 | 52 | @unpublished{Edwards2016, 53 | Author = {Edwards, Benjamin and Jacobs, Jay and Forrest, Stephanie}, 54 | Date-Added = {2018-04-10 14:53:45 +0000}, 55 | Date-Modified = {2018-04-10 15:00:15 +0000}, 56 | Note = {Pre-print}, 57 | Title = {Risky Business: Assessing Security with External Measurements}, 58 | Year = {2016}, 59 | } 60 | --------------------------------------------------------------------------------