├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ ├── lint.yaml │ ├── pkgdown.yaml │ └── test-coverage.yaml ├── .gitignore ├── CITATION.cff ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DESCRIPTION ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── ggmice.R ├── old_friends.R ├── plot_corr.R ├── plot_flux.R ├── plot_pattern.R ├── plot_pred.R ├── plot_trace.R ├── theme.R └── utils.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── cran-comments.md ├── ggmice.Rproj ├── man ├── bwplot.Rd ├── densityplot.Rd ├── figures │ ├── README-example-1.png │ ├── README-example-2.png │ └── logo.png ├── ggmice.Rd ├── pipe.Rd ├── plot_corr.Rd ├── plot_flux.Rd ├── plot_pattern.Rd ├── plot_pred.Rd ├── plot_trace.Rd ├── stripplot.Rd ├── theme_mice.Rd ├── theme_minimice.Rd └── xyplot.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── revdep ├── .gitignore ├── README.md ├── cran.md ├── email.yml ├── failures.md └── problems.md ├── tests ├── testthat.R └── testthat │ ├── test-ggmice.R │ ├── test-old_friends.R │ ├── test-plot_corr.R │ ├── test-plot_flux.R │ ├── test-plot_pattern.R │ ├── test-plot_pred.R │ └── test-plot_trace.R └── vignettes ├── .gitignore ├── ggmice.Rmd └── old_friends.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^ggmice\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | ^CONTRIBUTING\.md$ 5 | ^README\.Rmd$ 6 | ^\.github$ 7 | ^doc$ 8 | ^Meta$ 9 | ^_pkgdown\.yml$ 10 | ^docs$ 11 | ^pkgdown$ 12 | ^CODE_OF_CONDUCT\.md$ 13 | ^CRAN_COMMENTS\.md$ 14 | ^codecov\.yml$ 15 | ^CRAN-SUBMISSION$ 16 | ^cran-comments\.md$ 17 | ^CITATION\.cff$ 18 | ^revdep$ 19 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master, dev] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macOS-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v2 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-r@v2 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v2 43 | with: 44 | extra-packages: rcmdcheck 45 | 46 | - uses: r-lib/actions/check-r-package@v2 47 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: lint 10 | 11 | jobs: 12 | lint: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - uses: r-lib/actions/setup-r@v2 20 | with: 21 | use-public-rspm: true 22 | 23 | - uses: r-lib/actions/setup-r-dependencies@v2 24 | with: 25 | extra-packages: any::lintr, local::. 26 | needs: lint 27 | 28 | - name: Lint 29 | run: lintr::lint_package(linters = lintr::linters_with_defaults( 30 | line_length_linter = lintr::line_length_linter(150), 31 | cyclocomp_linter = lintr::cyclocomp_linter(complexity_limit = 30L) 32 | )) 33 | shell: Rscript {0} 34 | env: 35 | LINTR_ERROR_ON_LINT: false 36 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::pkgdown, local::. 34 | needs: website 35 | 36 | - name: Build site 37 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 38 | shell: Rscript {0} 39 | 40 | - name: Deploy to GitHub pages 🚀 41 | if: github.event_name != 'pull_request' 42 | uses: JamesIves/github-pages-deploy-action@v4.4.1 43 | with: 44 | clean: false 45 | branch: gh-pages 46 | folder: docs 47 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: covr 27 | 28 | - name: Test coverage 29 | run: covr::codecov() 30 | shell: Rscript {0} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .Rdata 4 | .httr-oauth 5 | .DS_Store 6 | inst/doc 7 | /doc/ 8 | /Meta/ 9 | docs 10 | *.psd 11 | *.pdf 12 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # This CITATION.cff file was generated with cffinit. 2 | # Visit https://bit.ly/cffinit to generate yours today! 3 | 4 | cff-version: 1.2.0 5 | title: ggmice 6 | message: Please cite this software using these metadata. 7 | type: software 8 | authors: 9 | - given-names: Hanne Ida 10 | family-names: Oberman 11 | email: h.i.oberman@uu.nl 12 | affiliation: Utrecht University 13 | orcid: 'https://orcid.org/0000-0003-3276-2141' 14 | repository-code: 'https://github.com/amices/ggmice' 15 | url: 'https://amices.org/ggmice' 16 | repository: 'https://CRAN.R-project.org/package=ggmice' 17 | abstract: >- 18 | Enhance a 'mice' imputation workflow with 19 | visualizations for incomplete and/or imputed data. 20 | The plotting functions produce 'ggplot' objects 21 | which may be easily manipulated or extended. Use 22 | 'ggmice' to inspect missing data, develop 23 | imputation models, evaluate algorithmic 24 | convergence, or compare observed versus imputed 25 | data. 26 | keywords: 27 | - mice 28 | - visualization 29 | - ggplot2 30 | - missing data 31 | - r 32 | license: GPL-3.0+ 33 | commit: >- 34 | https://github.com/amices/ggmice/commit/fc5bb471a65307e8942a613f0f79423c893db1e2 35 | version: v0.0.1 36 | date-released: '2022-03-17' 37 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards 42 | of acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies 54 | when an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail 56 | address, posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at amices.org. 63 | All complaints will be reviewed and investigated promptly and fairly. 64 | 65 | All community leaders are obligated to respect the privacy and security of the 66 | reporter of any incident. 67 | 68 | ## Enforcement Guidelines 69 | 70 | Community leaders will follow these Community Impact Guidelines in determining 71 | the consequences for any action they deem in violation of this Code of Conduct: 72 | 73 | ### 1. Correction 74 | 75 | **Community Impact**: Use of inappropriate language or other behavior deemed 76 | unprofessional or unwelcome in the community. 77 | 78 | **Consequence**: A private, written warning from community leaders, providing 79 | clarity around the nature of the violation and an explanation of why the 80 | behavior was inappropriate. A public apology may be requested. 81 | 82 | ### 2. Warning 83 | 84 | **Community Impact**: A violation through a single incident or series of 85 | actions. 86 | 87 | **Consequence**: A warning with consequences for continued behavior. No 88 | interaction with the people involved, including unsolicited interaction with 89 | those enforcing the Code of Conduct, for a specified period of time. This 90 | includes avoiding interactions in community spaces as well as external channels 91 | like social media. Violating these terms may lead to a temporary or permanent 92 | ban. 93 | 94 | ### 3. Temporary Ban 95 | 96 | **Community Impact**: A serious violation of community standards, including 97 | sustained inappropriate behavior. 98 | 99 | **Consequence**: A temporary ban from any sort of interaction or public 100 | communication with the community for a specified period of time. No public or 101 | private interaction with the people involved, including unsolicited interaction 102 | with those enforcing the Code of Conduct, is allowed during this period. 103 | Violating these terms may lead to a permanent ban. 104 | 105 | ### 4. Permanent Ban 106 | 107 | **Community Impact**: Demonstrating a pattern of violation of community 108 | standards, including sustained inappropriate behavior, harassment of an 109 | individual, or aggression toward or disparagement of classes of individuals. 110 | 111 | **Consequence**: A permanent ban from any sort of public interaction within the 112 | community. 113 | 114 | ## Attribution 115 | 116 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 117 | version 2.0, 118 | available at . 119 | 120 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 121 | enforcement ladder](https://github.com/mozilla/diversity). 122 | 123 | [homepage]: https://www.contributor-covenant.org 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | . Translations are available at . 127 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributing to `ggmice` 3 | 4 | First off, thanks for taking the time to contribute! 5 | 6 | All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 7 | 8 | > And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: 9 | > - Star the project 10 | > - Post about it on Mastodon or Twitter 11 | > - Refer this project in your project's readme 12 | > - Mention the project at local meetups and tell your friends/colleagues 13 | > - Cite the package in your publications 14 | 15 | 16 | ## Table of Contents 17 | 18 | - [Code of Conduct](#code-of-conduct) 19 | - [I Have a Question](#i-have-a-question) 20 | - [I Want To Contribute](#i-want-to-contribute) 21 | - [Reporting Bugs](#reporting-bugs) 22 | - [Suggesting Enhancements](#suggesting-enhancements) 23 | - [Code Contributions](#code-contributions) 24 | - [Other contributions](#other-contributions) 25 | - [Styleguides](#styleguides) 26 | 27 | 28 | ## Code of Conduct 29 | 30 | This project and everyone participating in it is governed by the 31 | [Code of Conduct](https://github.com/amices/ggmice/blob/main/CODE_OF_CONDUCT.md). 32 | By participating, you are expected to uphold this code. Please report unacceptable behavior 33 | to . 34 | 35 | 36 | ## I Have a Question 37 | 38 | > If you want to ask a question, we assume that you have read the available [Documentation](https://amices.org/ggmice/). 39 | 40 | Before you ask a question, it is best to search for existing [Discussions](https://github.com/amices/ggmice/discussions) that might help you. In case you have found a suitable discussion and still need clarification, you can write your question in this discussion. It is also advisable to search the internet for answers first. 41 | 42 | If you then still feel the need to ask a question and need clarification, we recommend the following: 43 | 44 | - Open a [Discussion](https://github.com/amices/ggmice/discussions/new). 45 | - Provide as much context as you can about what you're running into. 46 | - Provide project and platform versions (e.g. R version), depending on what seems relevant. 47 | 48 | We will then take care of the issue as soon as possible. 49 | 50 | 64 | 65 | ## I Want To Contribute 66 | 67 | > ### Legal Notice 68 | > When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. 69 | 70 | ### Reporting Bugs 71 | 72 | 73 | #### Before Submitting a Bug Report 74 | 75 | A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. 76 | 77 | - Make sure that you are using the latest version. 78 | - Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://amices.org/ggmice/). If you are looking for support, you might want to check [this section](#i-have-a-question)). 79 | - To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/amices/ggmice/issues?q=label%3Abug). 80 | - Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. 81 | - Collect information about the bug: 82 | - Stack trace (Traceback) 83 | - OS, Platform and Version (Windows, Linux, macOS, x86, ARM) 84 | - Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant. 85 | - Possibly your input and the output 86 | - Can you reliably reproduce the issue? And can you also reproduce it with older versions? 87 | - Can you generate a reproducible example with the [`reprex`](https://reprex.tidyverse.org/) package? 88 | 89 | 90 | 91 | #### How Do I Submit a Good Bug Report? 92 | 93 | > You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to . 94 | 95 | 96 | We use GitHub issues to track bugs and errors. If you run into an issue with the project: 97 | 98 | - Open an [Issue](https://github.com/amices/ggmice/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.) 99 | - Explain the behavior you would expect and the actual behavior. 100 | - Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. 101 | - Provide the information you collected in the previous section. 102 | - Please include a reproducible example generated with the [`reprex`](https://reprex.tidyverse.org/) package. 103 | 104 | Once it's filed: 105 | 106 | - The project team will label the issue accordingly. 107 | - A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps. Bugs will not be addressed until they can be reproduced. 108 | - If the team is able to reproduce the issue, it will be marked `bug`, as well as possibly other tags (such as `help-wanted`), and the issue will be left to be [implemented by someone](#your-first-code-contribution). 109 | 110 | 111 | 112 | 113 | ### Suggesting Enhancements 114 | 115 | This section guides you through submitting an enhancement suggestion for `ggmice`, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. 116 | 117 | 118 | #### Before Submitting an Enhancement 119 | 120 | - Make sure that you are using the latest version. 121 | - Read the [documentation](https://amices.org/ggmice/) carefully and find out if the functionality is already covered, maybe by an individual configuration. 122 | - Perform a [search](https://github.com/amices/ggmice/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. 123 | - Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. 124 | 125 | 126 | #### How Do I Submit a Good Enhancement Suggestion? 127 | 128 | Enhancement suggestions are tracked as [GitHub issues](https://github.com/amices/ggmice/issues). 129 | 130 | - Use a **clear and descriptive title** for the issue to identify the suggestion. 131 | - Provide a **step-by-step description of the suggested enhancement** in as many details as possible. 132 | - **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. 133 | - You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. 134 | - **Explain why this enhancement would be useful** to most `ggmice` users. You may also want to point out the other projects that solved it better and which could serve as inspiration. 135 | 136 | 137 | 138 | ### Code Contributions 139 | 140 | To become a `ggmice` contributor, please fork the repository and commit your proposed changes to your fork. After pushing the changes and creating a pull request, the `ggmice` team will evaluate your contribution. 141 | 142 | If your contribution is related to a [`ggmice` issue](https://github.com/amices/ggmice/issues), include the issue number in your commit message(s) and pull request. If the issue has the label `bug`, please write a unit test for the concerning bug with the [`testthat` package](https://testthat.r-lib.org/). 143 | 144 | 148 | 149 | ### Other contributions 150 | 154 | We welcome all contributions to the `ggmice` project. 155 | 156 | For example, please interact on the [Discussions](https://github.com/amices/ggmice/discussions) forum, and help fellow `ggmice` users with their questions. 157 | 158 | To improve the `ggmice` documentation, please suggest changes to the `README.Rmd` file, the R markdown vignette files in the `vignettes` folder, or use [roxygen2](https://roxygen2.r-lib.org/) to edit the function documentation. 159 | 160 | 161 | ## Styleguides 162 | 163 | Please adhere to the [tidyverse style guide](https://style.tidyverse.org/). 164 | 165 | We're very happy that you'd like to contribute. To get the appropriate acknowledgement for your contribution, please add your name and [ORCID](https://orcid.org/) to the DESCRIPTION file at the root of the package. 166 | 167 | 168 | 169 | ## Attribution 170 | 171 | This guide is based on the [CONTRIBUTING.md](https://contributing.md/) generator, [**contributing-gen**](https://generator.contributing.md/). 172 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ggmice 2 | Title: Visualizations for 'mice' with 'ggplot2' 3 | Version: 0.1.0.9000 4 | Authors@R: c( 5 | person("Hanne", "Oberman", email = "h.i.oberman@uu.nl", role = c("aut", "cre"), 6 | comment = c(ORCID = "0000-0003-3276-2141")), 7 | person("Utrecht University", role = "fnd"), 8 | person("University Medical Centre Utrecht", role = "fnd"), 9 | person("Thom", "Volker", role = "ctb", comment = c(ORCID = "0000-0002-2408-7820")), 10 | person("Gerko", "Vink", role = "ctb", comment = c(ORCID = "0000-0001-9767-1924")), 11 | person("Pepijn", "Vink", role = "ctb", comment = c(ORCID = "0000-0001-6960-9904")), 12 | person("Jamie", "Wallis", role = "ctb", comment = c(ORCID = "0000-0003-2765-3813")), 13 | person("Kyle", "Lang", role = "ctb", comment = c(ORCID = "0000-0001-5340-7849")) 14 | ) 15 | Description: Enhance a 'mice' imputation workflow with visualizations for 16 | incomplete and/or imputed data. The plotting functions produce 17 | 'ggplot' objects which may be easily manipulated or extended. Use 18 | 'ggmice' to inspect missing data, develop imputation models, evaluate 19 | algorithmic convergence, or compare observed versus imputed data. 20 | License: GPL (>= 3) 21 | URL: https://github.com/amices/ggmice, https://amices.org/, 22 | https://amices.org/ggmice/ 23 | BugReports: https://github.com/amices/ggmice 24 | Imports: 25 | cli, 26 | dplyr, 27 | ggplot2, 28 | magrittr, 29 | mice, 30 | purrr, 31 | rlang, 32 | stats, 33 | stringr, 34 | tidyr, 35 | tidyselect, 36 | utils 37 | Suggests: 38 | covr, 39 | knitr, 40 | patchwork, 41 | plotly, 42 | rmarkdown, 43 | testthat (>= 3.0.0) 44 | VignetteBuilder: 45 | knitr 46 | Config/testthat/edition: 3 47 | Copyright: 'ggmice' authors 48 | Encoding: UTF-8 49 | Roxygen: list(markdown = TRUE) 50 | RoxygenNote: 7.3.2 51 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU General Public License 2 | ========================== 3 | 4 | _Version 3, 29 June 2007_ 5 | _Copyright © 2007 Free Software Foundation, Inc. <>_ 6 | 7 | Everyone is permitted to copy and distribute verbatim copies of this license 8 | document, but changing it is not allowed. 9 | 10 | ## Preamble 11 | 12 | The GNU General Public License is a free, copyleft license for software and other 13 | kinds of works. 14 | 15 | The licenses for most software and other practical works are designed to take away 16 | your freedom to share and change the works. By contrast, the GNU General Public 17 | License is intended to guarantee your freedom to share and change all versions of a 18 | program--to make sure it remains free software for all its users. We, the Free 19 | Software Foundation, use the GNU General Public License for most of our software; it 20 | applies also to any other work released this way by its authors. You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not price. Our General 24 | Public Licenses are designed to make sure that you have the freedom to distribute 25 | copies of free software (and charge for them if you wish), that you receive source 26 | code or can get it if you want it, that you can change the software or use pieces of 27 | it in new free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you these rights or 30 | asking you to surrender the rights. Therefore, you have certain responsibilities if 31 | you distribute copies of the software, or if you modify it: responsibilities to 32 | respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether gratis or for a fee, 35 | you must pass on to the recipients the same freedoms that you received. You must make 36 | sure that they, too, receive or can get the source code. And you must show them these 37 | terms so they know their rights. 38 | 39 | Developers that use the GNU GPL protect your rights with two steps: **(1)** assert 40 | copyright on the software, and **(2)** offer you this License giving you legal permission 41 | to copy, distribute and/or modify it. 42 | 43 | For the developers' and authors' protection, the GPL clearly explains that there is 44 | no warranty for this free software. For both users' and authors' sake, the GPL 45 | requires that modified versions be marked as changed, so that their problems will not 46 | be attributed erroneously to authors of previous versions. 47 | 48 | Some devices are designed to deny users access to install or run modified versions of 49 | the software inside them, although the manufacturer can do so. This is fundamentally 50 | incompatible with the aim of protecting users' freedom to change the software. The 51 | systematic pattern of such abuse occurs in the area of products for individuals to 52 | use, which is precisely where it is most unacceptable. Therefore, we have designed 53 | this version of the GPL to prohibit the practice for those products. If such problems 54 | arise substantially in other domains, we stand ready to extend this provision to 55 | those domains in future versions of the GPL, as needed to protect the freedom of 56 | users. 57 | 58 | Finally, every program is threatened constantly by software patents. States should 59 | not allow patents to restrict development and use of software on general-purpose 60 | computers, but in those that do, we wish to avoid the special danger that patents 61 | applied to a free program could make it effectively proprietary. To prevent this, the 62 | GPL assures that patents cannot be used to render the program non-free. 63 | 64 | The precise terms and conditions for copying, distribution and modification follow. 65 | 66 | ## TERMS AND CONDITIONS 67 | 68 | ### 0. Definitions 69 | 70 | “This License” refers to version 3 of the GNU General Public License. 71 | 72 | “Copyright” also means copyright-like laws that apply to other kinds of 73 | works, such as semiconductor masks. 74 | 75 | “The Program” refers to any copyrightable work licensed under this 76 | License. Each licensee is addressed as “you”. “Licensees” and 77 | “recipients” may be individuals or organizations. 78 | 79 | To “modify” a work means to copy from or adapt all or part of the work in 80 | a fashion requiring copyright permission, other than the making of an exact copy. The 81 | resulting work is called a “modified version” of the earlier work or a 82 | work “based on” the earlier work. 83 | 84 | A “covered work” means either the unmodified Program or a work based on 85 | the Program. 86 | 87 | To “propagate” a work means to do anything with it that, without 88 | permission, would make you directly or secondarily liable for infringement under 89 | applicable copyright law, except executing it on a computer or modifying a private 90 | copy. Propagation includes copying, distribution (with or without modification), 91 | making available to the public, and in some countries other activities as well. 92 | 93 | To “convey” a work means any kind of propagation that enables other 94 | parties to make or receive copies. Mere interaction with a user through a computer 95 | network, with no transfer of a copy, is not conveying. 96 | 97 | An interactive user interface displays “Appropriate Legal Notices” to the 98 | extent that it includes a convenient and prominently visible feature that **(1)** 99 | displays an appropriate copyright notice, and **(2)** tells the user that there is no 100 | warranty for the work (except to the extent that warranties are provided), that 101 | licensees may convey the work under this License, and how to view a copy of this 102 | License. If the interface presents a list of user commands or options, such as a 103 | menu, a prominent item in the list meets this criterion. 104 | 105 | ### 1. Source Code 106 | 107 | The “source code” for a work means the preferred form of the work for 108 | making modifications to it. “Object code” means any non-source form of a 109 | work. 110 | 111 | A “Standard Interface” means an interface that either is an official 112 | standard defined by a recognized standards body, or, in the case of interfaces 113 | specified for a particular programming language, one that is widely used among 114 | developers working in that language. 115 | 116 | The “System Libraries” of an executable work include anything, other than 117 | the work as a whole, that **(a)** is included in the normal form of packaging a Major 118 | Component, but which is not part of that Major Component, and **(b)** serves only to 119 | enable use of the work with that Major Component, or to implement a Standard 120 | Interface for which an implementation is available to the public in source code form. 121 | A “Major Component”, in this context, means a major essential component 122 | (kernel, window system, and so on) of the specific operating system (if any) on which 123 | the executable work runs, or a compiler used to produce the work, or an object code 124 | interpreter used to run it. 125 | 126 | The “Corresponding Source” for a work in object code form means all the 127 | source code needed to generate, install, and (for an executable work) run the object 128 | code and to modify the work, including scripts to control those activities. However, 129 | it does not include the work's System Libraries, or general-purpose tools or 130 | generally available free programs which are used unmodified in performing those 131 | activities but which are not part of the work. For example, Corresponding Source 132 | includes interface definition files associated with source files for the work, and 133 | the source code for shared libraries and dynamically linked subprograms that the work 134 | is specifically designed to require, such as by intimate data communication or 135 | control flow between those subprograms and other parts of the work. 136 | 137 | The Corresponding Source need not include anything that users can regenerate 138 | automatically from other parts of the Corresponding Source. 139 | 140 | The Corresponding Source for a work in source code form is that same work. 141 | 142 | ### 2. Basic Permissions 143 | 144 | All rights granted under this License are granted for the term of copyright on the 145 | Program, and are irrevocable provided the stated conditions are met. This License 146 | explicitly affirms your unlimited permission to run the unmodified Program. The 147 | output from running a covered work is covered by this License only if the output, 148 | given its content, constitutes a covered work. This License acknowledges your rights 149 | of fair use or other equivalent, as provided by copyright law. 150 | 151 | You may make, run and propagate covered works that you do not convey, without 152 | conditions so long as your license otherwise remains in force. You may convey covered 153 | works to others for the sole purpose of having them make modifications exclusively 154 | for you, or provide you with facilities for running those works, provided that you 155 | comply with the terms of this License in conveying all material for which you do not 156 | control copyright. Those thus making or running the covered works for you must do so 157 | exclusively on your behalf, under your direction and control, on terms that prohibit 158 | them from making any copies of your copyrighted material outside their relationship 159 | with you. 160 | 161 | Conveying under any other circumstances is permitted solely under the conditions 162 | stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 163 | 164 | ### 3. Protecting Users' Legal Rights From Anti-Circumvention Law 165 | 166 | No covered work shall be deemed part of an effective technological measure under any 167 | applicable law fulfilling obligations under article 11 of the WIPO copyright treaty 168 | adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention 169 | of such measures. 170 | 171 | When you convey a covered work, you waive any legal power to forbid circumvention of 172 | technological measures to the extent such circumvention is effected by exercising 173 | rights under this License with respect to the covered work, and you disclaim any 174 | intention to limit operation or modification of the work as a means of enforcing, 175 | against the work's users, your or third parties' legal rights to forbid circumvention 176 | of technological measures. 177 | 178 | ### 4. Conveying Verbatim Copies 179 | 180 | You may convey verbatim copies of the Program's source code as you receive it, in any 181 | medium, provided that you conspicuously and appropriately publish on each copy an 182 | appropriate copyright notice; keep intact all notices stating that this License and 183 | any non-permissive terms added in accord with section 7 apply to the code; keep 184 | intact all notices of the absence of any warranty; and give all recipients a copy of 185 | this License along with the Program. 186 | 187 | You may charge any price or no price for each copy that you convey, and you may offer 188 | support or warranty protection for a fee. 189 | 190 | ### 5. Conveying Modified Source Versions 191 | 192 | You may convey a work based on the Program, or the modifications to produce it from 193 | the Program, in the form of source code under the terms of section 4, provided that 194 | you also meet all of these conditions: 195 | 196 | * **a)** The work must carry prominent notices stating that you modified it, and giving a 197 | relevant date. 198 | * **b)** The work must carry prominent notices stating that it is released under this 199 | License and any conditions added under section 7. This requirement modifies the 200 | requirement in section 4 to “keep intact all notices”. 201 | * **c)** You must license the entire work, as a whole, under this License to anyone who 202 | comes into possession of a copy. This License will therefore apply, along with any 203 | applicable section 7 additional terms, to the whole of the work, and all its parts, 204 | regardless of how they are packaged. This License gives no permission to license the 205 | work in any other way, but it does not invalidate such permission if you have 206 | separately received it. 207 | * **d)** If the work has interactive user interfaces, each must display Appropriate Legal 208 | Notices; however, if the Program has interactive interfaces that do not display 209 | Appropriate Legal Notices, your work need not make them do so. 210 | 211 | A compilation of a covered work with other separate and independent works, which are 212 | not by their nature extensions of the covered work, and which are not combined with 213 | it such as to form a larger program, in or on a volume of a storage or distribution 214 | medium, is called an “aggregate” if the compilation and its resulting 215 | copyright are not used to limit the access or legal rights of the compilation's users 216 | beyond what the individual works permit. Inclusion of a covered work in an aggregate 217 | does not cause this License to apply to the other parts of the aggregate. 218 | 219 | ### 6. Conveying Non-Source Forms 220 | 221 | You may convey a covered work in object code form under the terms of sections 4 and 222 | 5, provided that you also convey the machine-readable Corresponding Source under the 223 | terms of this License, in one of these ways: 224 | 225 | * **a)** Convey the object code in, or embodied in, a physical product (including a 226 | physical distribution medium), accompanied by the Corresponding Source fixed on a 227 | durable physical medium customarily used for software interchange. 228 | * **b)** Convey the object code in, or embodied in, a physical product (including a 229 | physical distribution medium), accompanied by a written offer, valid for at least 230 | three years and valid for as long as you offer spare parts or customer support for 231 | that product model, to give anyone who possesses the object code either **(1)** a copy of 232 | the Corresponding Source for all the software in the product that is covered by this 233 | License, on a durable physical medium customarily used for software interchange, for 234 | a price no more than your reasonable cost of physically performing this conveying of 235 | source, or **(2)** access to copy the Corresponding Source from a network server at no 236 | charge. 237 | * **c)** Convey individual copies of the object code with a copy of the written offer to 238 | provide the Corresponding Source. This alternative is allowed only occasionally and 239 | noncommercially, and only if you received the object code with such an offer, in 240 | accord with subsection 6b. 241 | * **d)** Convey the object code by offering access from a designated place (gratis or for 242 | a charge), and offer equivalent access to the Corresponding Source in the same way 243 | through the same place at no further charge. You need not require recipients to copy 244 | the Corresponding Source along with the object code. If the place to copy the object 245 | code is a network server, the Corresponding Source may be on a different server 246 | (operated by you or a third party) that supports equivalent copying facilities, 247 | provided you maintain clear directions next to the object code saying where to find 248 | the Corresponding Source. Regardless of what server hosts the Corresponding Source, 249 | you remain obligated to ensure that it is available for as long as needed to satisfy 250 | these requirements. 251 | * **e)** Convey the object code using peer-to-peer transmission, provided you inform 252 | other peers where the object code and Corresponding Source of the work are being 253 | offered to the general public at no charge under subsection 6d. 254 | 255 | A separable portion of the object code, whose source code is excluded from the 256 | Corresponding Source as a System Library, need not be included in conveying the 257 | object code work. 258 | 259 | A “User Product” is either **(1)** a “consumer product”, which 260 | means any tangible personal property which is normally used for personal, family, or 261 | household purposes, or **(2)** anything designed or sold for incorporation into a 262 | dwelling. In determining whether a product is a consumer product, doubtful cases 263 | shall be resolved in favor of coverage. For a particular product received by a 264 | particular user, “normally used” refers to a typical or common use of 265 | that class of product, regardless of the status of the particular user or of the way 266 | in which the particular user actually uses, or expects or is expected to use, the 267 | product. A product is a consumer product regardless of whether the product has 268 | substantial commercial, industrial or non-consumer uses, unless such uses represent 269 | the only significant mode of use of the product. 270 | 271 | “Installation Information” for a User Product means any methods, 272 | procedures, authorization keys, or other information required to install and execute 273 | modified versions of a covered work in that User Product from a modified version of 274 | its Corresponding Source. The information must suffice to ensure that the continued 275 | functioning of the modified object code is in no case prevented or interfered with 276 | solely because modification has been made. 277 | 278 | If you convey an object code work under this section in, or with, or specifically for 279 | use in, a User Product, and the conveying occurs as part of a transaction in which 280 | the right of possession and use of the User Product is transferred to the recipient 281 | in perpetuity or for a fixed term (regardless of how the transaction is 282 | characterized), the Corresponding Source conveyed under this section must be 283 | accompanied by the Installation Information. But this requirement does not apply if 284 | neither you nor any third party retains the ability to install modified object code 285 | on the User Product (for example, the work has been installed in ROM). 286 | 287 | The requirement to provide Installation Information does not include a requirement to 288 | continue to provide support service, warranty, or updates for a work that has been 289 | modified or installed by the recipient, or for the User Product in which it has been 290 | modified or installed. Access to a network may be denied when the modification itself 291 | materially and adversely affects the operation of the network or violates the rules 292 | and protocols for communication across the network. 293 | 294 | Corresponding Source conveyed, and Installation Information provided, in accord with 295 | this section must be in a format that is publicly documented (and with an 296 | implementation available to the public in source code form), and must require no 297 | special password or key for unpacking, reading or copying. 298 | 299 | ### 7. Additional Terms 300 | 301 | “Additional permissions” are terms that supplement the terms of this 302 | License by making exceptions from one or more of its conditions. Additional 303 | permissions that are applicable to the entire Program shall be treated as though they 304 | were included in this License, to the extent that they are valid under applicable 305 | law. If additional permissions apply only to part of the Program, that part may be 306 | used separately under those permissions, but the entire Program remains governed by 307 | this License without regard to the additional permissions. 308 | 309 | When you convey a copy of a covered work, you may at your option remove any 310 | additional permissions from that copy, or from any part of it. (Additional 311 | permissions may be written to require their own removal in certain cases when you 312 | modify the work.) You may place additional permissions on material, added by you to a 313 | covered work, for which you have or can give appropriate copyright permission. 314 | 315 | Notwithstanding any other provision of this License, for material you add to a 316 | covered work, you may (if authorized by the copyright holders of that material) 317 | supplement the terms of this License with terms: 318 | 319 | * **a)** Disclaiming warranty or limiting liability differently from the terms of 320 | sections 15 and 16 of this License; or 321 | * **b)** Requiring preservation of specified reasonable legal notices or author 322 | attributions in that material or in the Appropriate Legal Notices displayed by works 323 | containing it; or 324 | * **c)** Prohibiting misrepresentation of the origin of that material, or requiring that 325 | modified versions of such material be marked in reasonable ways as different from the 326 | original version; or 327 | * **d)** Limiting the use for publicity purposes of names of licensors or authors of the 328 | material; or 329 | * **e)** Declining to grant rights under trademark law for use of some trade names, 330 | trademarks, or service marks; or 331 | * **f)** Requiring indemnification of licensors and authors of that material by anyone 332 | who conveys the material (or modified versions of it) with contractual assumptions of 333 | liability to the recipient, for any liability that these contractual assumptions 334 | directly impose on those licensors and authors. 335 | 336 | All other non-permissive additional terms are considered “further 337 | restrictions” within the meaning of section 10. If the Program as you received 338 | it, or any part of it, contains a notice stating that it is governed by this License 339 | along with a term that is a further restriction, you may remove that term. If a 340 | license document contains a further restriction but permits relicensing or conveying 341 | under this License, you may add to a covered work material governed by the terms of 342 | that license document, provided that the further restriction does not survive such 343 | relicensing or conveying. 344 | 345 | If you add terms to a covered work in accord with this section, you must place, in 346 | the relevant source files, a statement of the additional terms that apply to those 347 | files, or a notice indicating where to find the applicable terms. 348 | 349 | Additional terms, permissive or non-permissive, may be stated in the form of a 350 | separately written license, or stated as exceptions; the above requirements apply 351 | either way. 352 | 353 | ### 8. Termination 354 | 355 | You may not propagate or modify a covered work except as expressly provided under 356 | this License. Any attempt otherwise to propagate or modify it is void, and will 357 | automatically terminate your rights under this License (including any patent licenses 358 | granted under the third paragraph of section 11). 359 | 360 | However, if you cease all violation of this License, then your license from a 361 | particular copyright holder is reinstated **(a)** provisionally, unless and until the 362 | copyright holder explicitly and finally terminates your license, and **(b)** permanently, 363 | if the copyright holder fails to notify you of the violation by some reasonable means 364 | prior to 60 days after the cessation. 365 | 366 | Moreover, your license from a particular copyright holder is reinstated permanently 367 | if the copyright holder notifies you of the violation by some reasonable means, this 368 | is the first time you have received notice of violation of this License (for any 369 | work) from that copyright holder, and you cure the violation prior to 30 days after 370 | your receipt of the notice. 371 | 372 | Termination of your rights under this section does not terminate the licenses of 373 | parties who have received copies or rights from you under this License. If your 374 | rights have been terminated and not permanently reinstated, you do not qualify to 375 | receive new licenses for the same material under section 10. 376 | 377 | ### 9. Acceptance Not Required for Having Copies 378 | 379 | You are not required to accept this License in order to receive or run a copy of the 380 | Program. Ancillary propagation of a covered work occurring solely as a consequence of 381 | using peer-to-peer transmission to receive a copy likewise does not require 382 | acceptance. However, nothing other than this License grants you permission to 383 | propagate or modify any covered work. These actions infringe copyright if you do not 384 | accept this License. Therefore, by modifying or propagating a covered work, you 385 | indicate your acceptance of this License to do so. 386 | 387 | ### 10. Automatic Licensing of Downstream Recipients 388 | 389 | Each time you convey a covered work, the recipient automatically receives a license 390 | from the original licensors, to run, modify and propagate that work, subject to this 391 | License. You are not responsible for enforcing compliance by third parties with this 392 | License. 393 | 394 | An “entity transaction” is a transaction transferring control of an 395 | organization, or substantially all assets of one, or subdividing an organization, or 396 | merging organizations. If propagation of a covered work results from an entity 397 | transaction, each party to that transaction who receives a copy of the work also 398 | receives whatever licenses to the work the party's predecessor in interest had or 399 | could give under the previous paragraph, plus a right to possession of the 400 | Corresponding Source of the work from the predecessor in interest, if the predecessor 401 | has it or can get it with reasonable efforts. 402 | 403 | You may not impose any further restrictions on the exercise of the rights granted or 404 | affirmed under this License. For example, you may not impose a license fee, royalty, 405 | or other charge for exercise of rights granted under this License, and you may not 406 | initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging 407 | that any patent claim is infringed by making, using, selling, offering for sale, or 408 | importing the Program or any portion of it. 409 | 410 | ### 11. Patents 411 | 412 | A “contributor” is a copyright holder who authorizes use under this 413 | License of the Program or a work on which the Program is based. The work thus 414 | licensed is called the contributor's “contributor version”. 415 | 416 | A contributor's “essential patent claims” are all patent claims owned or 417 | controlled by the contributor, whether already acquired or hereafter acquired, that 418 | would be infringed by some manner, permitted by this License, of making, using, or 419 | selling its contributor version, but do not include claims that would be infringed 420 | only as a consequence of further modification of the contributor version. For 421 | purposes of this definition, “control” includes the right to grant patent 422 | sublicenses in a manner consistent with the requirements of this License. 423 | 424 | Each contributor grants you a non-exclusive, worldwide, royalty-free patent license 425 | under the contributor's essential patent claims, to make, use, sell, offer for sale, 426 | import and otherwise run, modify and propagate the contents of its contributor 427 | version. 428 | 429 | In the following three paragraphs, a “patent license” is any express 430 | agreement or commitment, however denominated, not to enforce a patent (such as an 431 | express permission to practice a patent or covenant not to sue for patent 432 | infringement). To “grant” such a patent license to a party means to make 433 | such an agreement or commitment not to enforce a patent against the party. 434 | 435 | If you convey a covered work, knowingly relying on a patent license, and the 436 | Corresponding Source of the work is not available for anyone to copy, free of charge 437 | and under the terms of this License, through a publicly available network server or 438 | other readily accessible means, then you must either **(1)** cause the Corresponding 439 | Source to be so available, or **(2)** arrange to deprive yourself of the benefit of the 440 | patent license for this particular work, or **(3)** arrange, in a manner consistent with 441 | the requirements of this License, to extend the patent license to downstream 442 | recipients. “Knowingly relying” means you have actual knowledge that, but 443 | for the patent license, your conveying the covered work in a country, or your 444 | recipient's use of the covered work in a country, would infringe one or more 445 | identifiable patents in that country that you have reason to believe are valid. 446 | 447 | If, pursuant to or in connection with a single transaction or arrangement, you 448 | convey, or propagate by procuring conveyance of, a covered work, and grant a patent 449 | license to some of the parties receiving the covered work authorizing them to use, 450 | propagate, modify or convey a specific copy of the covered work, then the patent 451 | license you grant is automatically extended to all recipients of the covered work and 452 | works based on it. 453 | 454 | A patent license is “discriminatory” if it does not include within the 455 | scope of its coverage, prohibits the exercise of, or is conditioned on the 456 | non-exercise of one or more of the rights that are specifically granted under this 457 | License. You may not convey a covered work if you are a party to an arrangement with 458 | a third party that is in the business of distributing software, under which you make 459 | payment to the third party based on the extent of your activity of conveying the 460 | work, and under which the third party grants, to any of the parties who would receive 461 | the covered work from you, a discriminatory patent license **(a)** in connection with 462 | copies of the covered work conveyed by you (or copies made from those copies), or **(b)** 463 | primarily for and in connection with specific products or compilations that contain 464 | the covered work, unless you entered into that arrangement, or that patent license 465 | was granted, prior to 28 March 2007. 466 | 467 | Nothing in this License shall be construed as excluding or limiting any implied 468 | license or other defenses to infringement that may otherwise be available to you 469 | under applicable patent law. 470 | 471 | ### 12. No Surrender of Others' Freedom 472 | 473 | If conditions are imposed on you (whether by court order, agreement or otherwise) 474 | that contradict the conditions of this License, they do not excuse you from the 475 | conditions of this License. If you cannot convey a covered work so as to satisfy 476 | simultaneously your obligations under this License and any other pertinent 477 | obligations, then as a consequence you may not convey it at all. For example, if you 478 | agree to terms that obligate you to collect a royalty for further conveying from 479 | those to whom you convey the Program, the only way you could satisfy both those terms 480 | and this License would be to refrain entirely from conveying the Program. 481 | 482 | ### 13. Use with the GNU Affero General Public License 483 | 484 | Notwithstanding any other provision of this License, you have permission to link or 485 | combine any covered work with a work licensed under version 3 of the GNU Affero 486 | General Public License into a single combined work, and to convey the resulting work. 487 | The terms of this License will continue to apply to the part which is the covered 488 | work, but the special requirements of the GNU Affero General Public License, section 489 | 13, concerning interaction through a network will apply to the combination as such. 490 | 491 | ### 14. Revised Versions of this License 492 | 493 | The Free Software Foundation may publish revised and/or new versions of the GNU 494 | General Public License from time to time. Such new versions will be similar in spirit 495 | to the present version, but may differ in detail to address new problems or concerns. 496 | 497 | Each version is given a distinguishing version number. If the Program specifies that 498 | a certain numbered version of the GNU General Public License “or any later 499 | version” applies to it, you have the option of following the terms and 500 | conditions either of that numbered version or of any later version published by the 501 | Free Software Foundation. If the Program does not specify a version number of the GNU 502 | General Public License, you may choose any version ever published by the Free 503 | Software Foundation. 504 | 505 | If the Program specifies that a proxy can decide which future versions of the GNU 506 | General Public License can be used, that proxy's public statement of acceptance of a 507 | version permanently authorizes you to choose that version for the Program. 508 | 509 | Later license versions may give you additional or different permissions. However, no 510 | additional obligations are imposed on any author or copyright holder as a result of 511 | your choosing to follow a later version. 512 | 513 | ### 15. Disclaimer of Warranty 514 | 515 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 516 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 517 | PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER 518 | EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 519 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE 520 | QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 521 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 522 | 523 | ### 16. Limitation of Liability 524 | 525 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY 526 | COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS 527 | PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, 528 | INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 529 | PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE 530 | OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE 531 | WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 532 | POSSIBILITY OF SUCH DAMAGES. 533 | 534 | ### 17. Interpretation of Sections 15 and 16 535 | 536 | If the disclaimer of warranty and limitation of liability provided above cannot be 537 | given local legal effect according to their terms, reviewing courts shall apply local 538 | law that most closely approximates an absolute waiver of all civil liability in 539 | connection with the Program, unless a warranty or assumption of liability accompanies 540 | a copy of the Program in return for a fee. 541 | 542 | _END OF TERMS AND CONDITIONS_ 543 | 544 | ## How to Apply These Terms to Your New Programs 545 | 546 | If you develop a new program, and you want it to be of the greatest possible use to 547 | the public, the best way to achieve this is to make it free software which everyone 548 | can redistribute and change under these terms. 549 | 550 | To do so, attach the following notices to the program. It is safest to attach them 551 | to the start of each source file to most effectively state the exclusion of warranty; 552 | and each file should have at least the “copyright” line and a pointer to 553 | where the full notice is found. 554 | 555 | 556 | Copyright (C) 557 | 558 | This program is free software: you can redistribute it and/or modify 559 | it under the terms of the GNU General Public License as published by 560 | the Free Software Foundation, either version 3 of the License, or 561 | (at your option) any later version. 562 | 563 | This program is distributed in the hope that it will be useful, 564 | but WITHOUT ANY WARRANTY; without even the implied warranty of 565 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 566 | GNU General Public License for more details. 567 | 568 | You should have received a copy of the GNU General Public License 569 | along with this program. If not, see . 570 | 571 | Also add information on how to contact you by electronic and paper mail. 572 | 573 | If the program does terminal interaction, make it output a short notice like this 574 | when it starts in an interactive mode: 575 | 576 | Copyright (C) 577 | This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. 578 | This is free software, and you are welcome to redistribute it 579 | under certain conditions; type 'show c' for details. 580 | 581 | The hypothetical commands `show w` and `show c` should show the appropriate parts of 582 | the General Public License. Of course, your program's commands might be different; 583 | for a GUI interface, you would use an “about box”. 584 | 585 | You should also get your employer (if you work as a programmer) or school, if any, to 586 | sign a “copyright disclaimer” for the program, if necessary. For more 587 | information on this, and how to apply and follow the GNU GPL, see 588 | <>. 589 | 590 | The GNU General Public License does not permit incorporating your program into 591 | proprietary programs. If your program is a subroutine library, you may consider it 592 | more useful to permit linking proprietary applications with the library. If this is 593 | what you want to do, use the GNU Lesser General Public License instead of this 594 | License. But first, please read 595 | <>. 596 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(bwplot) 5 | export(densityplot) 6 | export(ggmice) 7 | export(plot_corr) 8 | export(plot_flux) 9 | export(plot_pattern) 10 | export(plot_pred) 11 | export(plot_trace) 12 | export(stripplot) 13 | export(xyplot) 14 | importFrom(magrittr,"%>%") 15 | importFrom(rlang,.data) 16 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # ggmice (development version) 2 | 3 | ## Bug fixes 4 | 5 | * Correct labeling of 'exclusion-restriction' variables in `plot_pred()` (#128) 6 | * Parsing of `vrb` argument in all `plot_*()` functions: variable name(s) from object in global environment now recognized using `!!` notation (#157) 7 | 8 | ## Minor changes 9 | 10 | * Miscellaneous documentation and vignette updates (#128) 11 | 12 | --- 13 | 14 | # ggmice 0.1.0 15 | 16 | ## Breaking changes 17 | 18 | * Default plotting behavior `plot_pattern()` creates missing data pattern plot with square tiles (#74) 19 | * Default plotting behavior `plot_pred()` creates predictor matrix plot with colored tiles and shows predictor values (#71, #74) 20 | 21 | ## New features 22 | 23 | * New optional argument `plot_pred()` shows methods vector with predictor matrix plot (#71) 24 | * New optional argument `plot_pattern()` hides less frequent patterns (#77) 25 | * New optional argument `plot_pattern()` hides legend caption (#111) 26 | 27 | ## Bug fixes 28 | 29 | * The `ggmice()` function now displays all imputed data (incl. over-imputed data; #54) 30 | * The `ggmice()` function now catches errors when `mapping` input contains log-transformation (#80) 31 | * The family of `plot_*` functions now handle vector inputs for `vrb` argument (#80) 32 | * The family of `plot_*` functions now handle `matrix` inputs for `data` argument (#108) 33 | * The family of `plot_*` functions now omit grid lines from tile plots (#35) 34 | * The `plot_pattern()` function now handles any `data.frame` input for `data` argument (#38, #77, #104, #112) 35 | 36 | ## Minor changes 37 | 38 | * Input validation for `data` argument `plot_*` functions (#85) 39 | * Input validation for `vrb` argument `plot_*` functions (#80) 40 | * Input validation for `mapping` argument `ggmice()` (#34, #90) 41 | * Vignette updates (#31, #35, #38) and other documentation (#45, #51) 42 | * The `plot_pattern()` function creates missing data pattern plot with more informative labels (#59, #111) 43 | 44 | --- 45 | 46 | # ggmice 0.0.1 47 | 48 | * First release of the package. 49 | -------------------------------------------------------------------------------- /R/ggmice.R: -------------------------------------------------------------------------------- 1 | #' Plot incomplete or imputed data 2 | #' 3 | #' @param data An incomplete dataset (of class `data.frame`), or an object of class [`mice::mids`]. 4 | #' @param mapping A list of aesthetic mappings created with [ggplot2::aes()]. 5 | #' 6 | #' @return An object of class [`ggplot2::ggplot`]. The [`ggmice::ggmice`] function returns output 7 | #' equivalent to [`ggplot2::ggplot`] output, with a few important exceptions: 8 | #' 9 | #' - The theme is set to [`ggmice::theme_mice`]. 10 | #' - The color scale is set to the [`mice::mdc`] colors. 11 | #' - The `colour` aesthetic is set to `.where`, an internally defined variable which distinguishes 12 | #' observed data from missing data or imputed data (for incomplete and imputed data, respectively). 13 | #' 14 | #' @examples 15 | #' dat <- mice::nhanes 16 | #' ggmice(dat, ggplot2::aes(x = age, y = bmi)) + ggplot2::geom_point() 17 | #' imp <- mice::mice(dat, print = FALSE) 18 | #' ggmice(imp, ggplot2::aes(x = age, y = bmi)) + ggplot2::geom_point() 19 | #' @seealso See the `ggmice` vignette to use the `ggmice()` function on 20 | #' [incomplete data](https://amices.org/ggmice/articles/ggmice.html#the-ggmice-function) 21 | #' or [imputed data](https://amices.org/ggmice/articles/ggmice.html#the-ggmice-function-1). 22 | #' @export 23 | ggmice <- function(data = NULL, 24 | mapping = ggplot2::aes()) { 25 | # validate inputs 26 | verify_data(data, df = TRUE, imp = TRUE) 27 | if (is.null(mapping$x) && is.null(mapping$y)) { 28 | cli::cli_abort( 29 | c( 30 | "At least one of the mapping arguments 'x' or 'y' is required.", 31 | "i" = "Supply variable name(s) with ggplot2::aes()." 32 | ) 33 | ) 34 | } 35 | if (is.character(mapping$x) || is.character(mapping$y)) { 36 | cli::cli_abort( 37 | c( 38 | "The mapping argument requires variable name(s) of type 'quosure', supplied with ggplot2::aes().", 39 | "x" = "You have supplied a string." 40 | ) 41 | ) 42 | } 43 | if (!is.null(mapping$colour)) { 44 | cli::cli_warn( 45 | c( 46 | "The aes() argument 'colour' has a special use in ggmice() and will be overwritten.", 47 | "i" = "Try using 'shape' or 'linetype' for additional mapping, or use faceting." 48 | ) 49 | ) 50 | } 51 | 52 | # extract variable names from mapping object 53 | if (is.data.frame(data)) { 54 | vrbs <- names(data) 55 | vrbs_num <- vrbs[purrr::map_lgl(data, is.numeric)] 56 | } 57 | if (mice::is.mids(data)) { 58 | vrbs <- names(data$data) 59 | vrbs_num <- vrbs[purrr::map_lgl(data$data, is.numeric)] 60 | } 61 | if (length(vrbs) > length(unique(vrbs))) { 62 | cli::cli_abort( 63 | c("The data must have unique column names.", "x" = "Duplication found in {vrbs[duplicated(vrbs)]}") 64 | ) 65 | } 66 | # extract mapping variables 67 | vrb_x <- match_mapping(data, vrbs, mapping$x) 68 | vrb_y <- match_mapping(data, vrbs, mapping$y) 69 | 70 | # edit data and mapping objects 71 | if (is.data.frame(data)) { 72 | where_xy <- rowSums(is.na(as.matrix(data[, c(vrb_x, vrb_y)]))) > 0L 73 | mice_data <- cbind(.where = factor( 74 | where_xy == 1, 75 | levels = c(FALSE, TRUE), 76 | labels = c("observed", "missing"), 77 | ordered = TRUE 78 | ), 79 | data) 80 | if (!is.null(mapping$x) && !is.null(mapping$y)) { 81 | mice_data <- dplyr::mutate( 82 | mice_data, 83 | dplyr::across( 84 | tidyselect::all_of(vrbs_num), 85 | ~ tidyr::replace_na(as.numeric(.x), -Inf) 86 | ), 87 | dplyr::across(tidyselect::all_of(vrbs[vrbs %nin% vrbs_num]), ~ { 88 | as.factor(tidyr::replace_na(as.character(.x), " ")) 89 | }) 90 | ) 91 | } 92 | mice_mapping <- 93 | utils::modifyList(mapping, ggplot2::aes(colour = .where)) 94 | mice_colors <- 95 | c("observed" = "#006CC2B3", 96 | "missing" = "#B61A51B3") 97 | } 98 | if (mice::is.mids(data)) { 99 | where_xy <- rowSums(as.matrix(data$where[, c(vrb_x, vrb_y)])) > 0L 100 | miss_xy <- 101 | rowSums(as.matrix(is.na(data$data[, c(vrb_x, vrb_y)]))) > 0L 102 | mice_data <- dplyr::mutate( 103 | rbind( 104 | data.frame( 105 | .where = "observed", 106 | .imp = 0, 107 | .id = rownames(data$data), 108 | data$data 109 | )[!miss_xy, ], 110 | data.frame(.where = "imputed", mice::complete(data, action = "long"))[where_xy, ] 111 | ), 112 | .where = factor( 113 | .where, 114 | levels = c("observed", "imputed"), 115 | ordered = TRUE 116 | ), 117 | .imp = factor(.imp, levels = 0:data$m, ordered = TRUE) 118 | ) 119 | mice_mapping <- 120 | utils::modifyList(mapping, ggplot2::aes(colour = .where)) 121 | mice_colors <- 122 | c("observed" = "#006CC2B3", 123 | "imputed" = "#B61A51B3") 124 | } 125 | 126 | # create plot 127 | gg <- ggplot2::ggplot(data = mice_data, mapping = mice_mapping) + 128 | ggplot2::scale_color_manual(values = mice_colors, 129 | name = "", 130 | drop = FALSE) + 131 | theme_mice() 132 | 133 | # edit plot to display missing values on the axes 134 | if (is.data.frame(data) && 135 | !is.null(mapping$x) && !is.null(mapping$y)) { 136 | gg <- gg + 137 | ggplot2::coord_cartesian(clip = "off") 138 | if (!is.null(mapping$x)) { 139 | if (vrb_x %nin% vrbs_num) { 140 | gg <- gg + 141 | ggplot2::scale_x_discrete(expand = ggplot2::expansion(add = c(0, 0.6))) 142 | } 143 | } 144 | if (!is.null(mapping$y)) { 145 | if (vrb_y %nin% vrbs_num) { 146 | gg <- gg + 147 | ggplot2::scale_y_discrete(expand = ggplot2::expansion(add = c(0, 0.6))) 148 | } 149 | } 150 | } 151 | 152 | # output 153 | return(gg) 154 | } 155 | 156 | #' Utils function to extract mapping variables 157 | #' 158 | #' @param data Incomplete dataset or mids object. 159 | #' @param vrbs Column names. 160 | #' @param mapping_in Mapping provided to ggmice(). 161 | #' @return Variable name from mapping_in argument matched on vrbs argument. 162 | #' @keywords internal 163 | #' @noRd 164 | match_mapping <- function(data, vrbs, mapping_in) { 165 | if (is.null(mapping_in)) { 166 | return(NULL) 167 | } 168 | # parse data 169 | if (mice::is.mids(data)) { 170 | mapping_data <- data$data 171 | } else { 172 | mapping_data <- data 173 | } 174 | # parse mapping 175 | mapping_text <- ggplot2::as_label(mapping_in) 176 | if (stringr::str_detect(mapping_text, "log\\(")) { 177 | cli::cli_abort( 178 | c( 179 | "Log transformations are currently not supported by ggmice() in the mapping input.", 180 | "i" = "Please transform the data input, or use the ggplot2::scale_*_continuous(trans='log10') function." 181 | ) 182 | ) 183 | } 184 | if (mapping_text %in% vrbs) { 185 | mapping_out <- mapping_text 186 | } 187 | if ((mice::is.mids(data) && 188 | mapping_text %in% c(".id", ".imp", ".where"))) { 189 | mapping_out <- NULL 190 | } 191 | if (!is.null(mapping_in) && 192 | mapping_text %nin% c(vrbs, ".id", ".imp", ".where")) { 193 | mapping_out <- vrbs[stringr::str_detect(mapping_text, vrbs)] 194 | if (identical(mapping_out, character(0)) || 195 | inherits(try(dplyr::mutate(mapping_data, 196 | !!rlang::parse_quo(mapping_text, env = rlang::current_env())), 197 | silent = TRUE) 198 | , "try-error")) { 199 | cli::cli_abort( 200 | c("Must provide a valid mapping variable.", "x" = "Mapping variable '{mapping_text}' not found in the data or imputations.") 201 | ) 202 | } else { 203 | cli::cli_warn( 204 | c( 205 | "Mapping variable '{mapping_text}' recognized internally as {mapping_out}.", 206 | "Please verify whether this matches the requested mapping variable." 207 | ) 208 | ) 209 | } 210 | } 211 | # output 212 | return(mapping_out) 213 | } 214 | -------------------------------------------------------------------------------- /R/old_friends.R: -------------------------------------------------------------------------------- 1 | # Plotting functions from the `mice` package 2 | 3 | #' Box-and-whisker plot of observed and imputed data 4 | #' 5 | #' @param ... Any arguments passed to the function. 6 | #' 7 | #' @return The output of [mice::bwplot] and a message about the `ggmice` equivalent. 8 | #' @export 9 | #' 10 | #' @examples 11 | #' imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 12 | #' bwplot(imp) 13 | bwplot <- function(...) { 14 | cli::cli_inform( 15 | c( 16 | "Hint: Did you know, an equivalent figure can be created with `ggmice()`?", 17 | "For example, to plot a variable named 'my_vrb' from a mids object called 'my_mids', run: ", 18 | " " = "ggmice(my_mids, ggplot2::aes(x = .imp, y = my_vrb)) +", 19 | " " = "ggplot2::geom_boxplot()", 20 | "i" = "See amices.org/ggmice for more info."), 21 | .frequency = "once", 22 | .frequency_id = "bwplot" 23 | ) 24 | mice::bwplot(...) 25 | } 26 | 27 | #' Densityplot of observed and imputed data 28 | #' 29 | #' @param ... Any arguments passed to the function. 30 | #' 31 | #' @return The output of [mice::densityplot] and a message about the `ggmice` equivalent. 32 | #' @export 33 | #' 34 | #' @examples 35 | #' imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 36 | #' densityplot(imp) 37 | densityplot <- function(...) { 38 | cli::cli_inform( 39 | c( 40 | "Hint: Did you know, an equivalent figure can be created with `ggmice()`?", 41 | "For example, to plot a variable named 'my_vrb' from a mids object called 'my_mids', run:", 42 | " " = "ggmice(my_mids, ggplot2::aes(x = my_vrb, group = .imp)) +", 43 | " " = "ggplot2::geom_density()", 44 | "i" = "See amices.org/ggmice for more info." 45 | ), 46 | .frequency = "once", 47 | .frequency_id = "densityplot" 48 | ) 49 | mice::densityplot(...) 50 | } 51 | 52 | #' Stripplot of observed and imputed data 53 | #' 54 | #' @param ... Any arguments passed to the function. 55 | #' 56 | #' @return The output of [mice::stripplot] and a message about the `ggmice` equivalent. 57 | #' @export 58 | #' 59 | #' @examples 60 | #' imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 61 | #' stripplot(imp) 62 | stripplot <- function(...) { 63 | cli::cli_inform( 64 | c( 65 | "Hint: Did you know, an equivalent figure can be created with `ggmice()`?", 66 | "For example, to plot a variable named 'my_vrb' from a mids object called 'my_mids', run:", 67 | " " = "ggmice(my_mids, ggplot2::aes(x = .imp, y = my_vrb)) +", 68 | " " = "ggplot2::geom_jitter()", 69 | "i" = "See amices.org/ggmice for more info." 70 | ), 71 | .frequency = "once", 72 | .frequency_id = "stripplot" 73 | ) 74 | mice::stripplot(...) 75 | } 76 | 77 | #' Scatterplot of observed and imputed data 78 | #' 79 | #' @param ... Any arguments passed to the function. 80 | #' 81 | #' @return The output of [mice::xyplot] and a message about the `ggmice` equivalent. 82 | #' @export 83 | #' 84 | #' @examples 85 | #' imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 86 | #' xyplot(imp, bmi ~ age) 87 | xyplot <- function(...) { 88 | cli::cli_inform( 89 | c( 90 | "Hint: Did you know, an equivalent figure can be created with `ggmice()`?", 91 | "For example, to plot 2 variables named 'my_x' and 'my_y' from a mids object called 'my_mids', run:", 92 | " " = "ggmice(my_mids, ggplot2::aes(x = my_x, y = my_y)) +", 93 | " " = "ggplot2::geom_point()", 94 | "i" = "See amices.org/ggmice for more info." 95 | ), 96 | .frequency = "once", 97 | .frequency_id = "xyplot" 98 | ) 99 | mice::xyplot(...) 100 | } 101 | -------------------------------------------------------------------------------- /R/plot_corr.R: -------------------------------------------------------------------------------- 1 | #' Plot correlations between (incomplete) variables 2 | #' 3 | #' @param data A dataset of class `data.frame`, `tibble`, or `matrix`. 4 | #' @param vrb String, vector, or unquoted expression with variable name(s), default is "all". 5 | #' @param label Logical indicating whether correlation values should be displayed. 6 | #' @param square Logical indicating whether the plot tiles should be squares. 7 | #' @param diagonal Logical indicating whether the correlation of each variable with itself should be displayed. 8 | #' @param rotate Logical indicating whether the variable name labels should be rotated 90 degrees. 9 | #' @param caption Logical indicating whether the figure caption should be displayed. 10 | #' 11 | #' @return An object of class [ggplot2::ggplot]. 12 | #' 13 | #' @examples 14 | #' # plot correlations for all columns 15 | #' plot_corr(mice::nhanes) 16 | #' 17 | #' # plot correlations for specific columns by supplying a character vector 18 | #' plot_corr(mice::nhanes, c("chl", "hyp")) 19 | #' 20 | #' # plot correlations for specific columns by supplying unquoted variable names 21 | #' plot_corr(mice::nhanes, c(chl, hyp)) 22 | #' 23 | #' # plot correlations for specific columns by passing an object with variable names 24 | #' # from the environment, unquoted with `!!` 25 | #' my_variables <- c("chl", "hyp") 26 | #' plot_corr(mice::nhanes, !!my_variables) 27 | #' # object with variable names must be unquoted with `!!` 28 | #' try(plot_corr(mice::nhanes, my_variables)) 29 | #' 30 | #' @export 31 | plot_corr <- 32 | function(data, 33 | vrb = "all", 34 | label = FALSE, 35 | square = TRUE, 36 | diagonal = FALSE, 37 | rotate = FALSE, 38 | caption = TRUE) { 39 | if (is.matrix(data) && ncol(data) > 1) { 40 | data <- as.data.frame(data) 41 | } 42 | verify_data(data = data, df = TRUE) 43 | vrb <- rlang::enexpr(vrb) 44 | vrb_matched <- match_vrb(vrb, names(data)) 45 | if (length(vrb_matched) < 2) { 46 | cli::cli_abort("The number of variables should be two or more to compute correlations.") 47 | } 48 | # check if any column is constant 49 | constants <- apply(data[, vrb_matched], MARGIN = 2, function(x) { 50 | all(is.na(x)) || max(x, na.rm = TRUE) == min(x, na.rm = TRUE) 51 | }) 52 | if (any(constants)) { 53 | vrb_matched <- vrb_matched[!constants] 54 | cli::cli_inform( 55 | c( 56 | "No correlations computed for variable(s):", 57 | " " = paste(names(constants[which(constants)]), collapse = ", "), 58 | "i" = "Correlations are undefined for constants." 59 | ) 60 | ) 61 | } 62 | # compute correlations 63 | p <- length(vrb_matched) 64 | corrs <- data.frame( 65 | vrb = rep(vrb_matched, each = p), 66 | prd = vrb_matched, 67 | corr = matrix( 68 | round(stats::cov2cor( 69 | stats::cov(data.matrix(data[, vrb_matched]), use = "pairwise.complete.obs") 70 | ), 2), 71 | nrow = p * p, 72 | byrow = TRUE 73 | ) 74 | ) 75 | if (!diagonal) { 76 | corrs[corrs$vrb == corrs$prd, "corr"] <- NA 77 | } 78 | # create plot 79 | gg <- 80 | ggplot2::ggplot(corrs, 81 | ggplot2::aes( 82 | x = .data$prd, 83 | y = .data$vrb, 84 | label = .data$corr, 85 | fill = .data$corr 86 | )) + 87 | ggplot2::geom_tile(color = "black", alpha = 0.6) + 88 | ggplot2::scale_x_discrete(limits = vrb_matched, position = "top") + 89 | ggplot2::scale_y_discrete(limits = rev(vrb_matched)) + 90 | ggplot2::scale_fill_gradient2( 91 | low = ggplot2::alpha("deepskyblue", 0.6), 92 | mid = "lightyellow", 93 | high = ggplot2::alpha("orangered", 0.6), 94 | na.value = "grey90", 95 | limits = c(-1, 1) 96 | ) + 97 | theme_minimice() 98 | if (caption) { 99 | gg <- gg + 100 | ggplot2::labs( 101 | x = "Imputation model predictor", 102 | y = "Variable to impute", 103 | fill = "Correlation* 104 | ", 105 | caption = "*pairwise complete observations" 106 | ) 107 | } else { 108 | gg <- gg + 109 | ggplot2::labs(x = "Imputation model predictor", y = "Variable to impute", fill = "Correlation") 110 | } 111 | if (label) { 112 | gg <- 113 | gg + ggplot2::geom_text(color = "black", 114 | show.legend = FALSE, 115 | na.rm = TRUE) 116 | } 117 | if (square) { 118 | gg <- gg + ggplot2::coord_fixed(expand = FALSE) 119 | } else { 120 | gg <- gg + ggplot2::coord_cartesian(expand = FALSE) 121 | } 122 | if (rotate) { 123 | gg <- 124 | gg + ggplot2::theme(axis.text.x.top = ggplot2::element_text(angle = 90)) 125 | } 126 | return(gg) 127 | } 128 | -------------------------------------------------------------------------------- /R/plot_flux.R: -------------------------------------------------------------------------------- 1 | #' Plot the influx and outflux of a multivariate missing data pattern 2 | #' 3 | #' @param data An incomplete dataset of class `data.frame` or `matrix`. 4 | #' @param vrb String, vector, or unquoted expression with variable name(s), default is "all". 5 | #' @param label Logical indicating whether variable names should be displayed within the plot (the default) or with colors in the legend. 6 | #' @param caption Logical indicating whether the figure caption should be displayed. 7 | #' 8 | #' @return An object of class [ggplot2::ggplot]. 9 | #' 10 | #' @examples 11 | #' # plot flux for all columns 12 | #' plot_flux(mice::nhanes) 13 | #' 14 | #' # plot flux for specific columns by supplying a character vector 15 | #' plot_flux(mice::nhanes, c("chl", "hyp")) 16 | #' 17 | #' # plot flux for specific columns by supplying unquoted variable names 18 | #' plot_flux(mice::nhanes, c(chl, hyp)) 19 | #' 20 | #' # plot flux for specific columns by passing an object with variable names 21 | #' # from the environment, unquoted with `!!` 22 | #' my_variables <- c("chl", "hyp") 23 | #' plot_flux(mice::nhanes, !!my_variables) 24 | #' # object with variable names must be unquoted with `!!` 25 | #' try(plot_flux(mice::nhanes, my_variables)) 26 | #' 27 | #' @export 28 | plot_flux <- 29 | function(data, 30 | vrb = "all", 31 | label = TRUE, 32 | caption = TRUE) { 33 | verify_data(data, df = TRUE) 34 | vrb <- rlang::enexpr(vrb) 35 | vrb_matched <- match_vrb(vrb, names(data)) 36 | if (length(vrb_matched) < 2) { 37 | cli::cli_abort("The number of variables should be two or more to compute flux.") 38 | } 39 | # compute flux 40 | flx <- mice::flux(data[, vrb_matched])[, c("influx", "outflux")] 41 | # create plot 42 | gg <- 43 | data.frame( 44 | vrb = rownames(flx), 45 | flx, 46 | outflux = flx$outflux - 0.025 47 | ) %>% 48 | ggplot2::ggplot( 49 | ggplot2::aes( 50 | x = .data$influx, 51 | y = .data$outflux, 52 | color = .data$vrb, 53 | label = .data$vrb 54 | ) 55 | ) + 56 | ggplot2::geom_abline( 57 | intercept = 1, 58 | slope = -1, 59 | linetype = "dashed" 60 | ) + 61 | ggplot2::lims(x = c(-0.05, 1.05), y = c(-0.05, 1.05)) + 62 | ggplot2::coord_cartesian(clip = "off") + 63 | theme_mice() 64 | if (label) { 65 | gg <- gg + 66 | ggplot2::geom_text( 67 | color = "black", 68 | position = ggplot2::position_nudge(y = 0.025) 69 | ) 70 | } else { 71 | gg <- gg + 72 | ggplot2::geom_point( 73 | shape = 1, 74 | position = ggplot2::position_nudge(y = 0.025) 75 | ) + 76 | ggplot2::labs(color = "") 77 | } 78 | if (caption) { 79 | gg <- gg + 80 | ggplot2::labs( 81 | x = "Influx*", 82 | y = "Outflux**", 83 | caption = "*connection of a variable's missingness indicator with observed data on other variables\n 84 | **connection of a variable's observed data with missing data on other variables" 85 | ) 86 | } else { 87 | gg <- gg + 88 | ggplot2::labs( 89 | x = "Influx", 90 | y = "Outflux" 91 | ) 92 | } 93 | # output 94 | return(gg) 95 | } 96 | -------------------------------------------------------------------------------- /R/plot_pattern.R: -------------------------------------------------------------------------------- 1 | #' Plot the missing data pattern of an incomplete dataset 2 | #' 3 | #' @param data An incomplete dataset of class `data.frame` or `matrix`. 4 | #' @param vrb String, vector, or unquoted expression with variable name(s), default is "all". 5 | #' @param square Logical indicating whether the plot tiles should be squares, defaults to squares to mimick `mice::md.pattern()`. 6 | #' @param rotate Logical indicating whether the variable name labels should be rotated 90 degrees. 7 | #' @param cluster Optional character string specifying which variable should be used for clustering (e.g., for multilevel data). 8 | #' @param npat Optional numeric input specifying the number of missing data patterns to be visualized, defaults to all patterns. 9 | #' @param caption Logical indicating whether the figure caption should be displayed. 10 | #' 11 | #' @return An object of class [ggplot2::ggplot]. 12 | #' 13 | #' @examples 14 | #' # plot missing data pattern for all columns 15 | #' plot_pattern(mice::nhanes) 16 | #' 17 | #' # plot missing data pattern for specific columns by supplying a character vector 18 | #' plot_pattern(mice::nhanes, c("chl", "hyp")) 19 | #' 20 | #' # plot missing data pattern for specific columns by supplying unquoted variable names 21 | #' plot_pattern(mice::nhanes, c(chl, hyp)) 22 | #' 23 | #' # plot missing data pattern for specific columns by passing an object with variable names 24 | #' # from the environment, unquoted with `!!` 25 | #' my_variables <- c("chl", "hyp") 26 | #' plot_pattern(mice::nhanes, !!my_variables) 27 | #' # object with variable names must be unquoted with `!!` 28 | #' try(plot_pattern(mice::nhanes, my_variables)) 29 | #' 30 | #' @export 31 | plot_pattern <- 32 | function(data, 33 | vrb = "all", 34 | square = TRUE, 35 | rotate = FALSE, 36 | cluster = NULL, 37 | npat = NULL, 38 | caption = TRUE) { 39 | if (is.matrix(data) && ncol(data) > 1) { 40 | data <- as.data.frame(data) 41 | } 42 | verify_data(data, df = TRUE) 43 | vrb <- rlang::enexpr(vrb) 44 | vrb_matched <- match_vrb(vrb, names(data)) 45 | if (length(vrb_matched) < 2) { 46 | cli::cli_abort("The number of variables should be two or more to compute missing data patterns.") 47 | } 48 | if (".x" %in% vrb_matched || ".y" %in% vrb_matched) { 49 | cli::cli_abort( 50 | c( 51 | "The variable names '.x' and '.y' are used internally to produce the missing data pattern plot.", 52 | "i" = "Please exclude or rename your variable(s)." 53 | ) 54 | ) 55 | } 56 | if (!is.null(cluster)) { 57 | if (cluster %nin% names(data[, vrb_matched])) { 58 | cli::cli_abort( 59 | c("Cluster variable not recognized.", 60 | "i" = "Please provide the variable name as a character string.") 61 | ) 62 | } 63 | } 64 | if (!is.null(npat)) { 65 | if (!is.numeric(npat) || npat < 1) { 66 | cli::cli_abort( 67 | c("The minimum number of patterns to display is one.", 68 | "i" = "Please provide a positive integer.") 69 | ) 70 | } 71 | } 72 | 73 | # get missing data pattern 74 | pat <- mice::md.pattern(data[, vrb_matched], plot = FALSE) 75 | rows_pat_full <- 76 | (nrow(pat) - 1) # full number of missing data patterns 77 | 78 | 79 | # filter npat most frequent patterns 80 | if (!is.null(npat)) { 81 | if (npat < rows_pat_full) { 82 | top_n_pat <- 83 | sort(as.numeric(row.names(pat)), decreasing = TRUE)[1:npat] 84 | pat <- 85 | pat[rownames(pat) %in% c(top_n_pat, ""), , drop = FALSE] 86 | 87 | if (npat != (nrow(pat) - 1)) { 88 | # if npat != number of missing patterns 89 | # show number of requested, shown, and hidden missing data patterns 90 | cli::cli_inform( 91 | c( 92 | "i" = "{npat} missing data patterns were requested.", 93 | "i" = "{nrow(pat) - 1} missing data patterns are shown.", 94 | "i" = "{rows_pat_full - (nrow(pat)-1)} missing data patterns are hidden." 95 | ) 96 | ) 97 | } 98 | } else { 99 | cli::cli_warn( 100 | c( 101 | "Number of patterns specified is equal to or greater than the total number of patterns.", 102 | "i" = "All missing data patterns are shown." 103 | ) 104 | ) 105 | } 106 | } 107 | 108 | # extract pattern info 109 | rws <- nrow(pat) 110 | cls <- ncol(pat) 111 | vrb <- colnames(pat)[-cls] 112 | frq <- row.names(pat)[-rws] 113 | na_row <- pat[-rws, cls] 114 | na_col <- pat[rws, -cls] 115 | 116 | # add opacity for clustering 117 | if (is.null(cluster)) { 118 | pat_clean <- cbind(.opacity = 1, pat[-rws, vrb, drop = FALSE]) 119 | } else { 120 | pats <- purrr::map(split(data[, vrb], ~ get(cluster)), ~ { 121 | mice::md.pattern(., plot = FALSE) %>% 122 | pat_to_chr(., ord = vrb) 123 | }) 124 | pat_used <- purrr::map_dfr(pats, ~ { 125 | pat_to_chr(pat) %in% .x 126 | }) %>% 127 | rowMeans() 128 | pat_clean <- data.frame(.opacity = pat_used, pat[-rws, vrb]) 129 | } 130 | 131 | # tidy the pattern 132 | long <- 133 | as.data.frame(cbind(.y = 1:(rws - 1), pat_clean)) %>% 134 | tidyr::pivot_longer( 135 | cols = tidyselect::all_of(vrb), 136 | names_to = "x", 137 | values_to = ".where" 138 | ) %>% 139 | dplyr::mutate( 140 | .x = as.numeric(factor( 141 | .data$x, 142 | levels = vrb, ordered = TRUE 143 | )), 144 | .where = factor( 145 | .data$.where, 146 | levels = c(0, 1), 147 | labels = c("missing", "observed") 148 | ), 149 | .opacity = as.numeric(.data$.opacity) 150 | ) 151 | 152 | # create the plot 153 | gg <- 154 | ggplot2::ggplot( 155 | long, 156 | ggplot2::aes( 157 | .data$.x, 158 | .data$.y, 159 | fill = .data$.where, 160 | alpha = 0.1 + .data$.opacity / 2 161 | ) 162 | ) + 163 | ggplot2::geom_tile(color = "black") + 164 | ggplot2::scale_fill_manual(values = c( 165 | "observed" = "#006CC2B3", 166 | "missing" = "#B61A51B3" 167 | )) + 168 | ggplot2::scale_alpha_continuous(limits = c(0, 1), guide = "none") + 169 | ggplot2::scale_x_continuous( 170 | breaks = 1:(cls - 1), 171 | labels = na_col, 172 | sec.axis = ggplot2::dup_axis(labels = vrb, 173 | name = "Column name") 174 | ) + 175 | ggplot2::scale_y_reverse( 176 | breaks = 1:(rws - 1), 177 | labels = frq, 178 | sec.axis = ggplot2::dup_axis(labels = na_row, 179 | name = "Number of missing entries\nper pattern") 180 | ) + 181 | ggplot2::labs( 182 | x = "Number of missing entries\nper column", 183 | y = "Pattern frequency", 184 | fill = "", 185 | alpha = "" 186 | ) + 187 | theme_minimice() 188 | 189 | # additional arguments 190 | if (square) { 191 | gg <- gg + ggplot2::coord_fixed(expand = FALSE) 192 | } else { 193 | gg <- gg + ggplot2::coord_cartesian(expand = FALSE) 194 | } 195 | if (rotate) { 196 | gg <- 197 | gg + ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 90)) 198 | } 199 | if (caption) { 200 | if (!is.null(npat) && npat < rows_pat_full) { 201 | gg <- gg + 202 | ggplot2::labs( 203 | x = "Number of missing entries\nper column*", 204 | y = "Pattern frequency**", 205 | caption = paste0( 206 | "*total number of missing entries: ", 207 | pat[rws, cls], 208 | "\n**number of patterns shown: ", 209 | (nrow(pat) - 1), 210 | " out of ", 211 | rows_pat_full, 212 | "" 213 | ) 214 | ) 215 | } else { 216 | gg <- gg + 217 | ggplot2::labs(x = "Number of missing entries\nper column*", 218 | caption = paste0("*total number of missing entries: ", 219 | pat[rws, cls])) 220 | } 221 | } 222 | 223 | return(gg) 224 | } 225 | 226 | #' Utils function to process missing data pattern 227 | #' 228 | #' @param pat Numeric matrix with a missing data pattern. 229 | #' @param ord Vector with variable names. 230 | #' @keywords internal 231 | #' @noRd 232 | pat_to_chr <- function(pat, ord = NULL) { 233 | if (is.null(ord)) { 234 | ord <- colnames(pat)[-ncol(pat)] 235 | } 236 | apply(pat[-nrow(pat), ord], 1, function(x) { 237 | paste(as.numeric(x), collapse = "") 238 | }) 239 | } 240 | -------------------------------------------------------------------------------- /R/plot_pred.R: -------------------------------------------------------------------------------- 1 | #' Plot the predictor matrix of an imputation model 2 | #' 3 | #' @param data A predictor matrix for `mice`, typically generated with [mice::make.predictorMatrix] or [mice::quickpred]. 4 | #' @param vrb String, vector, or unquoted expression with variable name(s), default is "all". 5 | #' @param method Character string or vector with imputation methods. 6 | #' @param label Logical indicating whether predictor matrix values should be displayed. 7 | #' @param square Logical indicating whether the plot tiles should be squares. 8 | #' @param rotate Logical indicating whether the variable name labels should be rotated 90 degrees. 9 | #' 10 | #' @return An object of class `ggplot2::ggplot`. 11 | #' 12 | #' @examples 13 | #' # generate a predictor matrix 14 | #' pred <- mice::quickpred(mice::nhanes) 15 | #' 16 | #' # plot predictor matrix for all columns 17 | #' plot_pred(pred) 18 | #' 19 | #' # plot predictor matrix for specific columns by supplying a character vector 20 | #' plot_pred(pred, c("chl", "hyp")) 21 | #' 22 | #' # plot predictor matrix for specific columns by supplying unquoted variable names 23 | #' plot_pred(pred, c(chl, hyp)) 24 | #' 25 | #' # plot predictor matrix for specific columns by passing an object with variable names 26 | #' # from the environment, unquoted with `!!` 27 | #' my_variables <- c("chl", "hyp") 28 | #' plot_pred(pred, !!my_variables) 29 | #' # object with variable names must be unquoted with `!!` 30 | #' try(plot_pred(pred, my_variables)) 31 | #' 32 | #' @export 33 | plot_pred <- 34 | function(data, 35 | vrb = "all", 36 | method = NULL, 37 | label = TRUE, 38 | square = TRUE, 39 | rotate = FALSE) { 40 | verify_data(data, pred = TRUE) 41 | vrb <- rlang::enexpr(vrb) 42 | vrb_matched <- match_vrb(vrb, row.names(data)) 43 | p <- length(vrb_matched) 44 | if (!is.null(method) && is.character(method)) { 45 | if (length(method) == 1) { 46 | method <- rep(method, p) 47 | } 48 | if (length(method) == p) { 49 | ylabel <- "Imputation method" 50 | } 51 | } 52 | if (is.null(method)) { 53 | method <- rep("", p) 54 | ylabel <- "" 55 | } 56 | if (!is.character(method) || length(method) != p) { 57 | cli::cli_abort("Method should be NULL or a character string or vector (of length 1 or `ncol(data)`).") 58 | } 59 | long <- data.frame( 60 | vrb = 1:p, 61 | prd = rep(vrb_matched, each = p), 62 | ind = matrix(data[vrb_matched, vrb_matched], nrow = p * p, byrow = TRUE) 63 | ) %>% dplyr::mutate(clr = factor( 64 | .data$ind, 65 | levels = c(-3, -2, 0, 1, 2), 66 | labels = c( 67 | "inclusion-restriction variable", 68 | "cluster variable", 69 | "not used", 70 | "predictor", 71 | "random effect" 72 | ), 73 | ordered = TRUE 74 | )) 75 | 76 | gg <- 77 | ggplot2::ggplot(long, 78 | ggplot2::aes( 79 | x = .data$prd, 80 | y = .data$vrb, 81 | label = .data$ind, 82 | fill = .data$clr 83 | )) + 84 | ggplot2::geom_tile(color = "black", alpha = 0.6) + 85 | ggplot2::scale_x_discrete(limits = vrb_matched, position = "top") + 86 | ggplot2::scale_y_reverse( 87 | breaks = 1:p, 88 | labels = vrb_matched, 89 | sec.axis = ggplot2::dup_axis(labels = method, name = ylabel) 90 | ) + 91 | ggplot2::scale_fill_manual( 92 | values = c( 93 | "inclusion-restriction variable" = "orangered", 94 | "cluster variable" = "lightyellow", 95 | "not used" = "grey90", 96 | "predictor" = "palegreen3", 97 | "random effect" = "deepskyblue" 98 | ) 99 | ) + 100 | ggplot2::labs( 101 | x = "Imputation model predictor", 102 | y = "Variable to impute", 103 | fill = "", 104 | color = "" 105 | ) + 106 | theme_minimice() 107 | 108 | if (all(method == "")) { 109 | gg <- 110 | gg + ggplot2::theme(axis.ticks.y.right = ggplot2::element_blank()) 111 | } 112 | if (label) { 113 | gg <- gg + ggplot2::geom_text(color = "black", show.legend = FALSE) 114 | } 115 | if (square) { 116 | gg <- gg + ggplot2::coord_fixed(expand = FALSE) 117 | } else { 118 | gg <- gg + ggplot2::coord_cartesian(expand = FALSE) 119 | } 120 | if (rotate) { 121 | gg <- 122 | gg + ggplot2::theme(axis.text.x.top = ggplot2::element_text(angle = 90)) 123 | } 124 | return(gg) 125 | } 126 | -------------------------------------------------------------------------------- /R/plot_trace.R: -------------------------------------------------------------------------------- 1 | #' Plot the trace lines of the imputation algorithm 2 | #' 3 | #' @param data An object of class [mice::mids]. 4 | #' @param vrb String, vector, or unquoted expression with variable name(s), 5 | #' default is "all". 6 | #' 7 | #' @details 8 | #' The `vrb` argument is "quoted" via [rlang::enexpr()] and evaluated according 9 | #' to [tidy evaluation principles](https://adv-r.hadley.nz/metaprogramming.html). 10 | #' In practice, this technical nuance only affects users when passing an object 11 | #' from the environment (e.g., a vector of variable names) to the `vrb` argument. 12 | #' In such cases, the object must be "unquoted" via the `!!` prefix operator. 13 | #' 14 | #' @returns An object of class [ggplot2::ggplot]. 15 | #' 16 | #' @examples 17 | #' # create [mice::mids] object with [mice::mice()] 18 | #' imp <- mice::mice(mice::nhanes, print = FALSE) 19 | #' 20 | #' # plot trace lines for all imputed columns 21 | #' plot_trace(imp) 22 | #' 23 | #' # plot trace lines for specific columns by supplying a string or character vector 24 | #' plot_trace(imp, "chl") 25 | #' plot_trace(imp, c("chl", "hyp")) 26 | 27 | #' # plot trace lines for specific columns by supplying unquoted variable names 28 | #' plot_trace(imp, chl) 29 | #' plot_trace(imp, c(chl, hyp)) 30 | #' 31 | #' # plot trace lines for specific columns by passing an object with variable names 32 | #' # from the environment, unquoted with `!!` 33 | #' my_variables <- c("chl", "hyp") 34 | #' plot_trace(imp, !!my_variables) 35 | #' # object with variable names must be unquoted with `!!` 36 | #' try(plot_trace(imp, my_variables)) 37 | #' 38 | #' @export 39 | plot_trace <- function(data, vrb = "all") { 40 | verify_data(data, imp = TRUE) 41 | if (is.null(data$chainMean) && is.null(data$chainVar)) { 42 | cli::cli_abort("No convergence diagnostics found", call. = FALSE) 43 | } 44 | vrb <- rlang::enexpr(vrb) 45 | vrbs_in_data <- names(data$imp) 46 | vrb_matched <- match_vrb(vrb, vrbs_in_data) 47 | # extract chain means and chain standard deviations 48 | mn <- data$chainMean 49 | sm <- sqrt(data$chainVar) 50 | available_vrbs <- vrbs_in_data[apply(!(is.nan(mn) | is.na(sm)), 1, all)] 51 | if (any(vrb_matched %nin% available_vrbs)) { 52 | cli::cli_inform( 53 | c( 54 | "Trace plot could not be produced for variable(s):", 55 | " " = paste(vrb_matched[which(vrb_matched %nin% available_vrbs)], collapse = ", "), 56 | "i" = "No convergence diagnostics found." 57 | ) 58 | ) 59 | } 60 | vrb_matched <- vrb_matched[which(vrb_matched %in% available_vrbs)] 61 | # compute diagnostics 62 | p <- length(vrb_matched) 63 | m <- data$m 64 | it <- data$iteration 65 | long <- cbind( 66 | expand.grid(.it = seq_len(it), .m = seq_len(m)), 67 | data.frame( 68 | .ms = rep(c("mean", "sd"), each = m * it * p), 69 | vrb_matched = rep(vrb_matched, each = m * it, times = 2), 70 | val = c( 71 | matrix(aperm(mn[vrb_matched, , , drop = FALSE], c( 72 | 2, 3, 1)), nrow = m * it * p), 73 | matrix(aperm(sm[vrb_matched, , , drop = FALSE], c( 74 | 2, 3, 1)), nrow = m * it * p) 75 | ) 76 | ) 77 | ) 78 | # create plot 79 | ggplot2::ggplot(long, 80 | ggplot2::aes( 81 | x = .data$.it, 82 | y = .data$val, 83 | color = as.factor(.data$.m) 84 | )) + 85 | ggplot2::geom_line(linewidth = 0.6) + 86 | ggplot2::geom_hline(yintercept = -Inf) + 87 | ggplot2::facet_wrap( 88 | .ms ~ vrb_matched, 89 | dir = "v", 90 | ncol = 2, 91 | scales = "free_y", 92 | strip.position = "left", 93 | labeller = function(labels) { 94 | labels <- lapply(labels, as.character) 95 | list(do.call(paste, c(labels, list(sep = "\n")))) 96 | } 97 | ) + 98 | ggplot2::labs(x = "Iteration", y = "Imputation parameter", color = "Imputation number") + 99 | theme_mice() + 100 | ggplot2::theme( 101 | strip.background = ggplot2::element_blank(), 102 | strip.placement = "outside", 103 | strip.switch.pad.wrap = ggplot2::unit(0, "cm") 104 | ) 105 | } 106 | -------------------------------------------------------------------------------- /R/theme.R: -------------------------------------------------------------------------------- 1 | #' Theme for [mice] style [ggplot2::ggplot] objects 2 | #' 3 | #' @return A [ggplot2] theme. 4 | theme_mice <- function() { 5 | ggplot2::theme_classic() + 6 | ggplot2::theme( 7 | legend.position = "bottom", 8 | legend.justification = "right", 9 | strip.placement = "outside" 10 | ) 11 | } 12 | 13 | #' Minimal theme for [mice] style [ggplot2::ggplot] objects 14 | #' 15 | #' @return A [ggplot2] theme. 16 | theme_minimice <- function() { 17 | ggplot2::theme_minimal() + 18 | ggplot2::theme( 19 | legend.position = "bottom", 20 | legend.justification = "right", 21 | strip.placement = "outside", 22 | panel.grid.minor = ggplot2::element_blank(), 23 | panel.grid.major = ggplot2::element_blank(), 24 | axis.ticks = ggplot2::element_line(colour = "black"), 25 | axis.title.y.right = ggplot2::element_text(margin = ggplot2::margin(l = 6)) 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | # Functions for internal use 2 | 3 | # Shorthand 'not in' for code readability 4 | `%nin%` <- Negate(`%in%`) 5 | 6 | #' Pipe operator 7 | #' 8 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 9 | #' 10 | #' @name %>% 11 | #' @rdname pipe 12 | #' @keywords internal 13 | #' @export 14 | #' @importFrom magrittr %>% 15 | #' @importFrom rlang .data 16 | #' @usage lhs \%>\% rhs 17 | #' @param lhs A value or the magrittr placeholder. 18 | #' @param rhs A function call using the magrittr semantics. 19 | #' @return The result of calling `rhs(lhs)`. 20 | NULL 21 | 22 | #' Utils function to validate data argument inputs 23 | #' 24 | #' @param data The input supplied to the 'data' argument. 25 | #' @param df Logical indicating whether 'data.frame' inputs are permitted. 26 | #' @param imp Logical indicating whether 'mids' inputs are permitted. 27 | #' @param pred Logical indicating whether predictor matrix inputs are permitted. 28 | #' 29 | #' @return Either nothing or an error. 30 | #' 31 | #' @keywords internal 32 | #' @noRd 33 | verify_data <- function(data, 34 | df = FALSE, 35 | imp = FALSE, 36 | pred = FALSE) { 37 | if (df && !imp) { 38 | if (!(is.data.frame(data) || is.matrix(data))) { 39 | cli::cli_abort( 40 | c( 41 | "The 'data' argument requires an object of class 'data.frame' or 'matrix'.", 42 | "i" = "Input object is of class {class(data)}." 43 | ), 44 | call. = FALSE 45 | ) 46 | } 47 | } 48 | if (df && imp) { 49 | if (!(is.data.frame(data) || 50 | is.matrix(data) || mice::is.mids(data))) { 51 | cli::cli_abort( 52 | c( 53 | "The 'data' argument requires an object of class 'data.frame', 'matrix', or 'mids'.", 54 | "i" = "Input object is of class {class(data)}." 55 | ), 56 | call. = FALSE 57 | ) 58 | } 59 | } 60 | if (imp && !df) { 61 | if (!mice::is.mids(data)) { 62 | cli::cli_abort( 63 | c( 64 | "The 'data' argument requires an object of class 'mids'.", 65 | "i" = "Input object is of class {class(data)}." 66 | ), 67 | call. = FALSE 68 | ) 69 | } 70 | } 71 | if (pred) { 72 | if (!is.matrix(data)) { 73 | cli::cli_abort( 74 | c( 75 | "The 'data' argument requires an object of class 'matrix'.", 76 | "i" = "Input object is of class {class(data)}." 77 | ), 78 | call. = FALSE 79 | ) 80 | } 81 | if (dim(data)[1] != dim(data)[2]) { 82 | cli::cli_abort( 83 | c( 84 | "The 'data' argument requires a square predictor matrix.", 85 | "i" = "Input object has {dim(data)[1]} rows and {dim(data)[2]} columns." 86 | ), 87 | call. = FALSE 88 | ) 89 | } 90 | if (is.null(rownames(data)) || is.null(colnames(data)) || 91 | !all.equal(rownames(data), colnames(data))) { 92 | cli::cli_warn( 93 | c( 94 | "The 'data' argument expects a square predictor matrix with equal row and column names.", 95 | "i" = "Try using `mice::make.predictorMatrix()` or `mice::quickpred()`." 96 | ), 97 | call. = FALSE 98 | ) 99 | } 100 | } 101 | } 102 | 103 | #' Utils function to match `vrb` argument to variable names in `data` 104 | #' 105 | #' @param vrb The input supplied to the 'vrb' argument. 106 | #' @param vrbs_in_data A character vector of available variable names in `data`. 107 | #' 108 | #' @return String or character vector with matched variable name(s). 109 | #' 110 | #' @keywords internal 111 | #' @noRd 112 | match_vrb <- function(vrb, vrbs_in_data) { 113 | if (is.call(vrb)) 114 | vrb <- as.character(vrb)[-1] 115 | if (is.symbol(vrb)) 116 | vrb <- as.character(vrb) 117 | if (length(vrb) == 1 && as.character(vrb) == "all") { 118 | vrb <- vrbs_in_data 119 | } 120 | if (all(vrb %nin% vrbs_in_data)) { 121 | cli::cli_abort( 122 | c( 123 | "x" = "The variable name(s) supplied to {.var vrb} could not be found in {.var data}.", 124 | "i" = "If you supply an object with variable names from the environment, use `!!` to unqote:", 125 | " " = paste0("{.code vrb = !!", vrb, "}") 126 | ) 127 | ) 128 | } 129 | if (any(vrb %nin% vrbs_in_data)) { 130 | cli::cli_warn(c("x" = "The following variables are not present in {.var data}:", " " = paste( 131 | setdiff(vrb, vrbs_in_data), collapse = ", " 132 | ))) 133 | } 134 | return(vrb) 135 | } 136 | 137 | # suppress undefined global functions or variables note 138 | utils::globalVariables(c(".id", ".imp", ".where", ".id", "where", "name", "value")) 139 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | ``` 15 | 16 | # `ggmice` 17 | 18 | 19 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/ggmice)](https://cran.r-project.org/package=ggmice) 20 | [![Total CRAN downloads](https://cranlogs.r-pkg.org/badges/grand-total/ggmice)](https://cranlogs.r-pkg.org/badges/grand-total/ggmice) 21 | [![r-universe status badge](https://amices.r-universe.dev/badges/ggmice)](https://amices.r-universe.dev/ggmice) 22 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6532702.svg)](https://doi.org/10.5281/zenodo.6532702) 23 | 24 | [![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) 25 | [![GitHub R package version](https://img.shields.io/github/r-package/v/amices/ggmice?color=yellow&label=dev)](https://github.com/amices/ggmice/blob/main/DESCRIPTION) 26 | [![R-CMD-check](https://github.com/amices/ggmice/workflows/R-CMD-check/badge.svg)](https://github.com/amices/ggmice/actions) 27 | 28 | 29 | ## Visualizations for `mice` with `ggplot2` 30 | 31 | Enhance a [`mice`](https://amices.org/mice/) imputation workflow with visualizations for incomplete and/or imputed data. The `ggmice` functions produce [`ggplot`](https://ggplot2.tidyverse.org/reference/ggplot) objects which may be easily manipulated or extended. Use `ggmice` to inspect missing data, develop imputation models, evaluate algorithmic convergence, or compare observed versus imputed data. 32 | 33 | ## Installation 34 | 35 | You can install the latest `ggmice` release from [CRAN](https://CRAN.R-project.org/package=ggmice) with: 36 | 37 | ``` r 38 | install.packages("ggmice") 39 | ``` 40 | 41 | Alternatively, you could install the development version of `ggmice` from [GitHub](https://github.com/amices) with: 42 | 43 | ``` r 44 | # install.packages("devtools") 45 | devtools::install_github("amices/ggmice") 46 | ``` 47 | 48 | ## Example 49 | 50 | Inspect the missing data in an incomplete dataset and subsequently evaluate the imputed data points against observed data. See the [Get started](https://amices.org/ggmice/articles/ggmice.html) vignette for an overview of all functionalities. Example data from [`mice`](https://amices.org/mice/reference/boys), showing height (in cm) by age (in years). 51 | 52 | ```{r example, message=FALSE, warning=FALSE, echo=TRUE, results='hide', fig.keep='all'} 53 | # load packages 54 | library(ggplot2) 55 | library(mice) 56 | library(ggmice) 57 | # load some data 58 | dat <- boys 59 | # visualize the incomplete data 60 | ggmice(dat, aes(age, hgt)) + geom_point() 61 | # impute the incomplete data 62 | imp <- mice(dat, m = 1, seed = 1) 63 | # visualize the imputed data 64 | ggmice(imp, aes(age, hgt)) + geom_point() 65 | ``` 66 | 67 | 68 | ## Acknowledgements 69 | 70 | The `ggmice` package is developed with guidance and feedback from the [Amices](https://github.com/amices) team. The `ggmice` hex is based on the [`ggplot2`](https://github.com/tidyverse/ggplot2/) and [`mice`](https://github.com/amices/mice) hex designs. 71 | 72 | This project has received funding from the European Union’s Horizon 2020 research and innovation programme under ReCoDID grant agreement No 825746. 73 | 74 | 75 | ## Code of Conduct 76 | 77 | You are invited to join the improvement and development of `ggmice`. Please note that the project is released with a [Contributor Code of Conduct](https://amices.org/ggmice/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. 78 | 79 | [![licence](https://img.shields.io/github/license/amices/ggmice?color=blue)](https://www.gnu.org/licenses/gpl-3.0.en.html) 80 | [![Codecov test coverage](https://codecov.io/gh/amices/ggmice/branch/main/graph/badge.svg)](https://app.codecov.io/gh/amices/ggmice?branch=main) 81 | [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6036/badge)](https://bestpractices.coreinfrastructure.org/projects/6036) 82 | [![fair-software.eu](https://img.shields.io/badge/fair--software.eu-%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F-green)](https://fair-software.eu) 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # `ggmice` 5 | 6 | 7 | 8 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/ggmice)](https://cran.r-project.org/package=ggmice) 9 | [![Total CRAN 10 | downloads](https://cranlogs.r-pkg.org/badges/grand-total/ggmice)](https://cranlogs.r-pkg.org/badges/grand-total/ggmice) 11 | [![r-universe status 12 | badge](https://amices.r-universe.dev/badges/ggmice)](https://amices.r-universe.dev/ggmice) 13 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6532702.svg)](https://doi.org/10.5281/zenodo.6532702) 14 | 15 | [![Lifecycle: 16 | stable](https://img.shields.io/badge/lifecycle-stable-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) 17 | [![GitHub R package 18 | version](https://img.shields.io/github/r-package/v/amices/ggmice?color=yellow&label=dev)](https://github.com/amices/ggmice/blob/main/DESCRIPTION) 19 | [![R-CMD-check](https://github.com/amices/ggmice/workflows/R-CMD-check/badge.svg)](https://github.com/amices/ggmice/actions) 20 | 21 | 22 | ## Visualizations for `mice` with `ggplot2` 23 | 24 | Enhance a [`mice`](https://amices.org/mice/) imputation workflow with 25 | visualizations for incomplete and/or imputed data. The `ggmice` 26 | functions produce 27 | [`ggplot`](https://ggplot2.tidyverse.org/reference/ggplot) objects which 28 | may be easily manipulated or extended. Use `ggmice` to inspect missing 29 | data, develop imputation models, evaluate algorithmic convergence, or 30 | compare observed versus imputed data. 31 | 32 | ## Installation 33 | 34 | You can install the latest `ggmice` release from 35 | [CRAN](https://CRAN.R-project.org/package=ggmice) with: 36 | 37 | ``` r 38 | install.packages("ggmice") 39 | ``` 40 | 41 | Alternatively, you could install the development version of `ggmice` 42 | from [GitHub](https://github.com/amices) with: 43 | 44 | ``` r 45 | # install.packages("devtools") 46 | devtools::install_github("amices/ggmice") 47 | ``` 48 | 49 | ## Example 50 | 51 | Inspect the missing data in an incomplete dataset and subsequently 52 | evaluate the imputed data points against observed data. See the [Get 53 | started](https://amices.org/ggmice/articles/ggmice.html) vignette for an 54 | overview of all functionalities. Example data from 55 | [`mice`](https://amices.org/mice/reference/boys), showing height (in cm) 56 | by age (in years). 57 | 58 | ``` r 59 | # load packages 60 | library(ggplot2) 61 | library(mice) 62 | library(ggmice) 63 | # load some data 64 | dat <- boys 65 | # visualize the incomplete data 66 | ggmice(dat, aes(age, hgt)) + geom_point() 67 | ``` 68 | 69 | 70 | 71 | ``` r 72 | # impute the incomplete data 73 | imp <- mice(dat, m = 1, seed = 1) 74 | # visualize the imputed data 75 | ggmice(imp, aes(age, hgt)) + geom_point() 76 | ``` 77 | 78 | 79 | 80 | ## Acknowledgements 81 | 82 | The `ggmice` package is developed with guidance and feedback from the 83 | [Amices](https://github.com/amices) team. The `ggmice` hex is based on 84 | the [`ggplot2`](https://github.com/tidyverse/ggplot2/) and 85 | [`mice`](https://github.com/amices/mice) hex designs. 86 | 87 | This project has received funding from the European Union’s Horizon 2020 88 | research and innovation programme under ReCoDID grant agreement No 89 | 825746. 90 | 91 | ## Code of Conduct 92 | 93 | You are invited to join the improvement and development of `ggmice`. 94 | Please note that the project is released with a [Contributor Code of 95 | Conduct](https://amices.org/ggmice/CODE_OF_CONDUCT.html). By 96 | contributing to this project, you agree to abide by its terms. 97 | 98 | [![licence](https://img.shields.io/github/license/amices/ggmice?color=blue)](https://www.gnu.org/licenses/gpl-3.0.en.html) 99 | [![Codecov test 100 | coverage](https://codecov.io/gh/amices/ggmice/branch/main/graph/badge.svg)](https://app.codecov.io/gh/amices/ggmice?branch=main) 101 | [![CII Best 102 | Practices](https://bestpractices.coreinfrastructure.org/projects/6036/badge)](https://bestpractices.coreinfrastructure.org/projects/6036) 103 | [![fair-software.eu](https://img.shields.io/badge/fair--software.eu-%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F-green)](https://fair-software.eu) 104 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: http://amices.org/ggmice/ 2 | template: 3 | bootstrap: 5 4 | reference: 5 | - subtitle: Core function 6 | - contents: 7 | - ggmice 8 | - subtitle: Other plotting functions 9 | - contents: 10 | - starts_with("plot_") 11 | - subtitle: Old friends 12 | - contents: 13 | - bwplot 14 | - densityplot 15 | - stripplot 16 | - xyplot 17 | - subtitle: Internal functions 18 | - contents: 19 | - theme_mice 20 | - theme_minimice 21 | figures: 22 | dev: ragg::agg_png 23 | dpi: 96 24 | dev.args: [] 25 | fig.ext: png 26 | fig.width: 7.2916667 27 | fig.height: ~ 28 | fig.retina: 2 29 | fig.asp: 1.618 30 | bg: NA 31 | other.parameters: [] 32 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | # ggmice 0.1.0 2 | 3 | ## R CMD check results 4 | 5 | 0 errors | 0 warnings | 0 notes 6 | 7 | ## Downstream dependencies 8 | 9 | There are no downstream dependencies of 'ggmice' yet. 10 | 11 | --- 12 | 13 | # ggmice 0.0.1 14 | 15 | ## Resubmission 16 | This is a resubmission. In this version I have: 17 | * Changed 'http' to 'https' in an invalid URL in the README file (as requested, thanks!). 18 | * Renamed the file CRAN_COMMENTS.md to cran-comments.md for compatibility with devtools::release(). 19 | * Changed the word 'workflows' to 'workflow' in the DESCRIPTION to avoid a NOTE about spelling. 20 | 21 | ## R CMD check results 22 | There were no ERRORs, WARNINGs or NOTEs. 23 | 24 | ## R CMD check results R-hub 25 | There were no ERRORs or WARNINGs. 26 | There were 2 NOTEs: 27 | 28 | > On windows-x86_64-devel (r-devel), ubuntu-gcc-release (r-release), fedora-clang-devel (r-devel) 29 | checking CRAN incoming feasibility ... NOTE 30 | Maintainer: 'Hanne Oberman ' 31 | New submission 32 | Version contains large components (0.0.0.9000) 33 | 34 | This NOTE is expected with a new submission. 35 | 36 | > On windows-x86_64-devel (r-devel) 37 | checking for detritus in the temp directory ... NOTE 38 | Found the following files/directories: 39 | 'lastMiKTeXException' 40 | 41 | This NOTE is due to a known and apparently harmless issue, see [rhub #503](https://github.com/r-hub/rhub/issues/503). 42 | 43 | ## R CMD check results win-devel 44 | There were no ERRORs or WARNINGs. 45 | There was 1 NOTE: 46 | 47 | > Using R Under development (unstable) (2022-03-14 r81896 ucrt), platform x86_64-w64-mingw32 (64-bit) 48 | checking CRAN incoming feasibility ... NOTE 49 | Maintainer: 'Hanne Oberman ' 50 | New submission 51 | Version contains large components (0.0.0.9000) 52 | 53 | This NOTE is expected with a new submission. 54 | 55 | ## Downstream dependencies 56 | There are no downstream dependencies of 'ggmice' yet. 57 | -------------------------------------------------------------------------------- /ggmice.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /man/bwplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/old_friends.R 3 | \name{bwplot} 4 | \alias{bwplot} 5 | \title{Box-and-whisker plot of observed and imputed data} 6 | \usage{ 7 | bwplot(...) 8 | } 9 | \arguments{ 10 | \item{...}{Any arguments passed to the function.} 11 | } 12 | \value{ 13 | The output of \link[mice:bwplot.mids]{mice::bwplot} and a message about the \code{ggmice} equivalent. 14 | } 15 | \description{ 16 | Box-and-whisker plot of observed and imputed data 17 | } 18 | \examples{ 19 | imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 20 | bwplot(imp) 21 | } 22 | -------------------------------------------------------------------------------- /man/densityplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/old_friends.R 3 | \name{densityplot} 4 | \alias{densityplot} 5 | \title{Densityplot of observed and imputed data} 6 | \usage{ 7 | densityplot(...) 8 | } 9 | \arguments{ 10 | \item{...}{Any arguments passed to the function.} 11 | } 12 | \value{ 13 | The output of \link[mice:densityplot.mids]{mice::densityplot} and a message about the \code{ggmice} equivalent. 14 | } 15 | \description{ 16 | Densityplot of observed and imputed data 17 | } 18 | \examples{ 19 | imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 20 | densityplot(imp) 21 | } 22 | -------------------------------------------------------------------------------- /man/figures/README-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/man/figures/README-example-1.png -------------------------------------------------------------------------------- /man/figures/README-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/man/figures/README-example-2.png -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/man/figures/logo.png -------------------------------------------------------------------------------- /man/ggmice.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggmice.R 3 | \name{ggmice} 4 | \alias{ggmice} 5 | \title{Plot incomplete or imputed data} 6 | \usage{ 7 | ggmice(data = NULL, mapping = ggplot2::aes()) 8 | } 9 | \arguments{ 10 | \item{data}{An incomplete dataset (of class \code{data.frame}), or an object of class \code{\link[mice:mids-class]{mice::mids}}.} 11 | 12 | \item{mapping}{A list of aesthetic mappings created with \code{\link[ggplot2:aes]{ggplot2::aes()}}.} 13 | } 14 | \value{ 15 | An object of class \code{\link[ggplot2:ggplot]{ggplot2::ggplot}}. The \code{\link{ggmice}} function returns output 16 | equivalent to \code{\link[ggplot2:ggplot]{ggplot2::ggplot}} output, with a few important exceptions: 17 | \itemize{ 18 | \item The theme is set to \code{\link{theme_mice}}. 19 | \item The color scale is set to the \code{\link[mice:mdc]{mice::mdc}} colors. 20 | \item The \code{colour} aesthetic is set to \code{.where}, an internally defined variable which distinguishes 21 | observed data from missing data or imputed data (for incomplete and imputed data, respectively). 22 | } 23 | } 24 | \description{ 25 | Plot incomplete or imputed data 26 | } 27 | \examples{ 28 | dat <- mice::nhanes 29 | ggmice(dat, ggplot2::aes(x = age, y = bmi)) + ggplot2::geom_point() 30 | imp <- mice::mice(dat, print = FALSE) 31 | ggmice(imp, ggplot2::aes(x = age, y = bmi)) + ggplot2::geom_point() 32 | } 33 | \seealso{ 34 | See the \code{ggmice} vignette to use the \code{ggmice()} function on 35 | \href{https://amices.org/ggmice/articles/ggmice.html#the-ggmice-function}{incomplete data} 36 | or \href{https://amices.org/ggmice/articles/ggmice.html#the-ggmice-function-1}{imputed data}. 37 | } 38 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \arguments{ 10 | \item{lhs}{A value or the magrittr placeholder.} 11 | 12 | \item{rhs}{A function call using the magrittr semantics.} 13 | } 14 | \value{ 15 | The result of calling \code{rhs(lhs)}. 16 | } 17 | \description{ 18 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man/plot_corr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_corr.R 3 | \name{plot_corr} 4 | \alias{plot_corr} 5 | \title{Plot correlations between (incomplete) variables} 6 | \usage{ 7 | plot_corr( 8 | data, 9 | vrb = "all", 10 | label = FALSE, 11 | square = TRUE, 12 | diagonal = FALSE, 13 | rotate = FALSE, 14 | caption = TRUE 15 | ) 16 | } 17 | \arguments{ 18 | \item{data}{A dataset of class \code{data.frame}, \code{tibble}, or \code{matrix}.} 19 | 20 | \item{vrb}{String, vector, or unquoted expression with variable name(s), default is "all".} 21 | 22 | \item{label}{Logical indicating whether correlation values should be displayed.} 23 | 24 | \item{square}{Logical indicating whether the plot tiles should be squares.} 25 | 26 | \item{diagonal}{Logical indicating whether the correlation of each variable with itself should be displayed.} 27 | 28 | \item{rotate}{Logical indicating whether the variable name labels should be rotated 90 degrees.} 29 | 30 | \item{caption}{Logical indicating whether the figure caption should be displayed.} 31 | } 32 | \value{ 33 | An object of class \link[ggplot2:ggplot]{ggplot2::ggplot}. 34 | } 35 | \description{ 36 | Plot correlations between (incomplete) variables 37 | } 38 | \examples{ 39 | # plot correlations for all columns 40 | plot_corr(mice::nhanes) 41 | 42 | # plot correlations for specific columns by supplying a character vector 43 | plot_corr(mice::nhanes, c("chl", "hyp")) 44 | 45 | # plot correlations for specific columns by supplying unquoted variable names 46 | plot_corr(mice::nhanes, c(chl, hyp)) 47 | 48 | # plot correlations for specific columns by passing an object with variable names 49 | # from the environment, unquoted with `!!` 50 | my_variables <- c("chl", "hyp") 51 | plot_corr(mice::nhanes, !!my_variables) 52 | # object with variable names must be unquoted with `!!` 53 | try(plot_corr(mice::nhanes, my_variables)) 54 | 55 | } 56 | -------------------------------------------------------------------------------- /man/plot_flux.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_flux.R 3 | \name{plot_flux} 4 | \alias{plot_flux} 5 | \title{Plot the influx and outflux of a multivariate missing data pattern} 6 | \usage{ 7 | plot_flux(data, vrb = "all", label = TRUE, caption = TRUE) 8 | } 9 | \arguments{ 10 | \item{data}{An incomplete dataset of class \code{data.frame} or \code{matrix}.} 11 | 12 | \item{vrb}{String, vector, or unquoted expression with variable name(s), default is "all".} 13 | 14 | \item{label}{Logical indicating whether variable names should be displayed within the plot (the default) or with colors in the legend.} 15 | 16 | \item{caption}{Logical indicating whether the figure caption should be displayed.} 17 | } 18 | \value{ 19 | An object of class \link[ggplot2:ggplot]{ggplot2::ggplot}. 20 | } 21 | \description{ 22 | Plot the influx and outflux of a multivariate missing data pattern 23 | } 24 | \examples{ 25 | # plot flux for all columns 26 | plot_flux(mice::nhanes) 27 | 28 | # plot flux for specific columns by supplying a character vector 29 | plot_flux(mice::nhanes, c("chl", "hyp")) 30 | 31 | # plot flux for specific columns by supplying unquoted variable names 32 | plot_flux(mice::nhanes, c(chl, hyp)) 33 | 34 | # plot flux for specific columns by passing an object with variable names 35 | # from the environment, unquoted with `!!` 36 | my_variables <- c("chl", "hyp") 37 | plot_flux(mice::nhanes, !!my_variables) 38 | # object with variable names must be unquoted with `!!` 39 | try(plot_flux(mice::nhanes, my_variables)) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /man/plot_pattern.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_pattern.R 3 | \name{plot_pattern} 4 | \alias{plot_pattern} 5 | \title{Plot the missing data pattern of an incomplete dataset} 6 | \usage{ 7 | plot_pattern( 8 | data, 9 | vrb = "all", 10 | square = TRUE, 11 | rotate = FALSE, 12 | cluster = NULL, 13 | npat = NULL, 14 | caption = TRUE 15 | ) 16 | } 17 | \arguments{ 18 | \item{data}{An incomplete dataset of class \code{data.frame} or \code{matrix}.} 19 | 20 | \item{vrb}{String, vector, or unquoted expression with variable name(s), default is "all".} 21 | 22 | \item{square}{Logical indicating whether the plot tiles should be squares, defaults to squares to mimick \code{mice::md.pattern()}.} 23 | 24 | \item{rotate}{Logical indicating whether the variable name labels should be rotated 90 degrees.} 25 | 26 | \item{cluster}{Optional character string specifying which variable should be used for clustering (e.g., for multilevel data).} 27 | 28 | \item{npat}{Optional numeric input specifying the number of missing data patterns to be visualized, defaults to all patterns.} 29 | 30 | \item{caption}{Logical indicating whether the figure caption should be displayed.} 31 | } 32 | \value{ 33 | An object of class \link[ggplot2:ggplot]{ggplot2::ggplot}. 34 | } 35 | \description{ 36 | Plot the missing data pattern of an incomplete dataset 37 | } 38 | \examples{ 39 | # plot missing data pattern for all columns 40 | plot_pattern(mice::nhanes) 41 | 42 | # plot missing data pattern for specific columns by supplying a character vector 43 | plot_pattern(mice::nhanes, c("chl", "hyp")) 44 | 45 | # plot missing data pattern for specific columns by supplying unquoted variable names 46 | plot_pattern(mice::nhanes, c(chl, hyp)) 47 | 48 | # plot missing data pattern for specific columns by passing an object with variable names 49 | # from the environment, unquoted with `!!` 50 | my_variables <- c("chl", "hyp") 51 | plot_pattern(mice::nhanes, !!my_variables) 52 | # object with variable names must be unquoted with `!!` 53 | try(plot_pattern(mice::nhanes, my_variables)) 54 | 55 | } 56 | -------------------------------------------------------------------------------- /man/plot_pred.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_pred.R 3 | \name{plot_pred} 4 | \alias{plot_pred} 5 | \title{Plot the predictor matrix of an imputation model} 6 | \usage{ 7 | plot_pred( 8 | data, 9 | vrb = "all", 10 | method = NULL, 11 | label = TRUE, 12 | square = TRUE, 13 | rotate = FALSE 14 | ) 15 | } 16 | \arguments{ 17 | \item{data}{A predictor matrix for \code{mice}, typically generated with \link[mice:make.predictorMatrix]{mice::make.predictorMatrix} or \link[mice:quickpred]{mice::quickpred}.} 18 | 19 | \item{vrb}{String, vector, or unquoted expression with variable name(s), default is "all".} 20 | 21 | \item{method}{Character string or vector with imputation methods.} 22 | 23 | \item{label}{Logical indicating whether predictor matrix values should be displayed.} 24 | 25 | \item{square}{Logical indicating whether the plot tiles should be squares.} 26 | 27 | \item{rotate}{Logical indicating whether the variable name labels should be rotated 90 degrees.} 28 | } 29 | \value{ 30 | An object of class \code{ggplot2::ggplot}. 31 | } 32 | \description{ 33 | Plot the predictor matrix of an imputation model 34 | } 35 | \examples{ 36 | # generate a predictor matrix 37 | pred <- mice::quickpred(mice::nhanes) 38 | 39 | # plot predictor matrix for all columns 40 | plot_pred(pred) 41 | 42 | # plot predictor matrix for specific columns by supplying a character vector 43 | plot_pred(pred, c("chl", "hyp")) 44 | 45 | # plot predictor matrix for specific columns by supplying unquoted variable names 46 | plot_pred(pred, c(chl, hyp)) 47 | 48 | # plot predictor matrix for specific columns by passing an object with variable names 49 | # from the environment, unquoted with `!!` 50 | my_variables <- c("chl", "hyp") 51 | plot_pred(pred, !!my_variables) 52 | # object with variable names must be unquoted with `!!` 53 | try(plot_pred(pred, my_variables)) 54 | 55 | } 56 | -------------------------------------------------------------------------------- /man/plot_trace.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_trace.R 3 | \name{plot_trace} 4 | \alias{plot_trace} 5 | \title{Plot the trace lines of the imputation algorithm} 6 | \usage{ 7 | plot_trace(data, vrb = "all") 8 | } 9 | \arguments{ 10 | \item{data}{An object of class \link[mice:mids-class]{mice::mids}.} 11 | 12 | \item{vrb}{String, vector, or unquoted expression with variable name(s), 13 | default is "all".} 14 | } 15 | \value{ 16 | An object of class \link[ggplot2:ggplot]{ggplot2::ggplot}. 17 | } 18 | \description{ 19 | Plot the trace lines of the imputation algorithm 20 | } 21 | \details{ 22 | The \code{vrb} argument is "quoted" via \code{\link[rlang:defusing-advanced]{rlang::enexpr()}} and evaluated according 23 | to \href{https://adv-r.hadley.nz/metaprogramming.html}{tidy evaluation principles}. 24 | In practice, this technical nuance only affects users when passing an object 25 | from the environment (e.g., a vector of variable names) to the \code{vrb} argument. 26 | In such cases, the object must be "unquoted" via the \verb{!!} prefix operator. 27 | } 28 | \examples{ 29 | # create [mice::mids] object with [mice::mice()] 30 | imp <- mice::mice(mice::nhanes, print = FALSE) 31 | 32 | # plot trace lines for all imputed columns 33 | plot_trace(imp) 34 | 35 | # plot trace lines for specific columns by supplying a string or character vector 36 | plot_trace(imp, "chl") 37 | plot_trace(imp, c("chl", "hyp")) 38 | # plot trace lines for specific columns by supplying unquoted variable names 39 | plot_trace(imp, chl) 40 | plot_trace(imp, c(chl, hyp)) 41 | 42 | # plot trace lines for specific columns by passing an object with variable names 43 | # from the environment, unquoted with `!!` 44 | my_variables <- c("chl", "hyp") 45 | plot_trace(imp, !!my_variables) 46 | # object with variable names must be unquoted with `!!` 47 | try(plot_trace(imp, my_variables)) 48 | 49 | } 50 | -------------------------------------------------------------------------------- /man/stripplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/old_friends.R 3 | \name{stripplot} 4 | \alias{stripplot} 5 | \title{Stripplot of observed and imputed data} 6 | \usage{ 7 | stripplot(...) 8 | } 9 | \arguments{ 10 | \item{...}{Any arguments passed to the function.} 11 | } 12 | \value{ 13 | The output of \link[mice:stripplot.mids]{mice::stripplot} and a message about the \code{ggmice} equivalent. 14 | } 15 | \description{ 16 | Stripplot of observed and imputed data 17 | } 18 | \examples{ 19 | imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 20 | stripplot(imp) 21 | } 22 | -------------------------------------------------------------------------------- /man/theme_mice.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme.R 3 | \name{theme_mice} 4 | \alias{theme_mice} 5 | \title{Theme for \link{mice} style \link[ggplot2:ggplot]{ggplot2::ggplot} objects} 6 | \usage{ 7 | theme_mice() 8 | } 9 | \value{ 10 | A \link{ggplot2} theme. 11 | } 12 | \description{ 13 | Theme for \link{mice} style \link[ggplot2:ggplot]{ggplot2::ggplot} objects 14 | } 15 | -------------------------------------------------------------------------------- /man/theme_minimice.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/theme.R 3 | \name{theme_minimice} 4 | \alias{theme_minimice} 5 | \title{Minimal theme for \link{mice} style \link[ggplot2:ggplot]{ggplot2::ggplot} objects} 6 | \usage{ 7 | theme_minimice() 8 | } 9 | \value{ 10 | A \link{ggplot2} theme. 11 | } 12 | \description{ 13 | Minimal theme for \link{mice} style \link[ggplot2:ggplot]{ggplot2::ggplot} objects 14 | } 15 | -------------------------------------------------------------------------------- /man/xyplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/old_friends.R 3 | \name{xyplot} 4 | \alias{xyplot} 5 | \title{Scatterplot of observed and imputed data} 6 | \usage{ 7 | xyplot(...) 8 | } 9 | \arguments{ 10 | \item{...}{Any arguments passed to the function.} 11 | } 12 | \value{ 13 | The output of \link[mice:xyplot.mids]{mice::xyplot} and a message about the \code{ggmice} equivalent. 14 | } 15 | \description{ 16 | Scatterplot of observed and imputed data 17 | } 18 | \examples{ 19 | imp <- mice::mice(mice::nhanes, maxit = 1, printFlag = FALSE) 20 | xyplot(imp, bmi ~ age) 21 | } 22 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amices/ggmice/41222e3b3b24d9f0f833c25320d44a3b6e9ec8be/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /revdep/.gitignore: -------------------------------------------------------------------------------- 1 | checks 2 | library 3 | checks.noindex 4 | library.noindex 5 | cloud.noindex 6 | data.sqlite 7 | *.html 8 | -------------------------------------------------------------------------------- /revdep/README.md: -------------------------------------------------------------------------------- 1 | # Platform 2 | 3 | |field |value | 4 | |:--------|:------------------------------------------------------------------------------------| 5 | |version |R version 4.3.0 (2023-04-21 ucrt) | 6 | |os |Windows 10 x64 (build 19045) | 7 | |system |x86_64, mingw32 | 8 | |ui |RStudio | 9 | |language |(EN) | 10 | |collate |Dutch_Netherlands.utf8 | 11 | |ctype |Dutch_Netherlands.utf8 | 12 | |tz |Europe/Amsterdam | 13 | |date |2023-07-24 | 14 | |rstudio |2023.06.1+524 Mountain Hydrangea (desktop) | 15 | |pandoc |3.1.1 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown) | 16 | 17 | # Dependencies 18 | 19 | |package |old |new |Δ | 20 | |:------------|:----------|:----------|:--| 21 | |ggmice |0.0.1 |0.0.1.9000 |* | 22 | |backports |1.4.1 |1.4.1 | | 23 | |bit |4.0.5 |4.0.5 | | 24 | |bit64 |4.0.5 |4.0.5 | | 25 | |brio |1.1.3 |1.1.3 | | 26 | |broom |1.0.5 |1.0.5 | | 27 | |callr |3.7.3 |3.7.3 | | 28 | |cli |3.6.1 |3.6.1 | | 29 | |clipr |0.8.0 |0.8.0 | | 30 | |colorspace |2.1-0 |2.1-0 | | 31 | |cpp11 |0.4.5 |0.4.5 | | 32 | |crayon |1.5.2 |1.5.2 | | 33 | |desc |1.4.2 |1.4.2 | | 34 | |diffobj |0.3.5 |0.3.5 | | 35 | |digest |0.6.33 |0.6.33 | | 36 | |dplyr |1.1.2 |1.1.2 | | 37 | |ellipsis |0.3.2 |0.3.2 | | 38 | |evaluate |0.21 |0.21 | | 39 | |fansi |1.0.4 |1.0.4 | | 40 | |farver |2.1.1 |2.1.1 | | 41 | |forcats |1.0.0 |1.0.0 | | 42 | |foreach |1.5.2 |1.5.2 | | 43 | |fs |1.6.3 |1.6.3 | | 44 | |generics |0.1.3 |0.1.3 | | 45 | |ggplot2 |3.4.2 |3.4.2 | | 46 | |glmnet |4.1-7 |4.1-7 | | 47 | |glue |1.6.2 |1.6.2 | | 48 | |gtable |0.3.3 |0.3.3 | | 49 | |haven |2.5.3 |2.5.3 | | 50 | |hms |1.1.3 |1.1.3 | | 51 | |isoband |0.2.7 |0.2.7 | | 52 | |iterators |1.0.14 |1.0.14 | | 53 | |jomo |2.7-6 |2.7-6 | | 54 | |jsonlite |1.8.7 |1.8.7 | | 55 | |labeling |0.4.2 |0.4.2 | | 56 | |lifecycle |1.0.3 |1.0.3 | | 57 | |lme4 |1.1-34 |1.1-34 | | 58 | |magrittr |2.0.3 |2.0.3 | | 59 | |mice |3.16.0 |3.16.0 | | 60 | |minqa |1.2.5 |1.2.5 | | 61 | |mitml |0.4-5 |0.4-5 | | 62 | |munsell |0.5.0 |0.5.0 | | 63 | |nloptr |2.0.3 |2.0.3 | | 64 | |numDeriv |2016.8-1.1 |2016.8-1.1 | | 65 | |ordinal |2022.11-16 |2022.11-16 | | 66 | |pan |1.8 |1.8 | | 67 | |pillar |1.9.0 |1.9.0 | | 68 | |pkgconfig |2.0.3 |2.0.3 | | 69 | |pkgload |1.3.2.1 |1.3.2.1 | | 70 | |praise |1.0.0 |1.0.0 | | 71 | |prettyunits |1.1.1 |1.1.1 | | 72 | |processx |3.8.2 |3.8.2 | | 73 | |progress |1.2.2 |1.2.2 | | 74 | |ps |1.7.5 |1.7.5 | | 75 | |purrr |1.0.1 |1.0.1 | | 76 | |R6 |2.5.1 |2.5.1 | | 77 | |RColorBrewer |1.1-3 |1.1-3 | | 78 | |Rcpp |1.0.11 |1.0.11 | | 79 | |RcppEigen |0.3.3.9.3 |0.3.3.9.3 | | 80 | |readr |2.1.4 |2.1.4 | | 81 | |rematch2 |2.1.2 |2.1.2 | | 82 | |rlang |1.1.1 |1.1.1 | | 83 | |rprojroot |2.0.3 |2.0.3 | | 84 | |scales |1.2.1 |1.2.1 | | 85 | |shape |1.4.6 |1.4.6 | | 86 | |stringi |1.7.12 |1.7.12 | | 87 | |stringr |1.5.0 |1.5.0 | | 88 | |testthat |3.1.10 |3.1.10 | | 89 | |tibble |3.2.1 |3.2.1 | | 90 | |tidyr |1.3.0 |1.3.0 | | 91 | |tidyselect |1.2.0 |1.2.0 | | 92 | |tzdb |0.4.0 |0.4.0 | | 93 | |ucminf |1.2.0 |1.2.0 | | 94 | |utf8 |1.2.3 |1.2.3 | | 95 | |vctrs |0.6.3 |0.6.3 | | 96 | |viridisLite |0.4.2 |0.4.2 | | 97 | |vroom |1.6.3 |1.6.3 | | 98 | |waldo |0.5.1 |0.5.1 | | 99 | |withr |2.5.0 |2.5.0 | | 100 | 101 | # Revdeps 102 | 103 | -------------------------------------------------------------------------------- /revdep/cran.md: -------------------------------------------------------------------------------- 1 | ## revdepcheck results 2 | 3 | We checked 0 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. 4 | 5 | * We saw 0 new problems 6 | * We failed to check 0 packages 7 | 8 | -------------------------------------------------------------------------------- /revdep/email.yml: -------------------------------------------------------------------------------- 1 | release_date: ??? 2 | rel_release_date: ??? 3 | my_news_url: ??? 4 | release_version: ??? 5 | release_details: ??? 6 | -------------------------------------------------------------------------------- /revdep/failures.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /revdep/problems.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(ggmice) 3 | 4 | set.seed(1) 5 | if (!interactive()) pdf(NULL) 6 | test_check("ggmice") 7 | -------------------------------------------------------------------------------- /tests/testthat/test-ggmice.R: -------------------------------------------------------------------------------- 1 | # create test objects 2 | dat <- dplyr::mutate( 3 | mice::nhanes, 4 | bmi = as.numeric(bmi), 5 | hyp = as.factor(hyp), 6 | age2 = as.character(age) 7 | ) 8 | imp <- suppressWarnings(mice::mice(dat, printFlag = FALSE)) 9 | 10 | # tests 11 | test_that("continuous data plot", { 12 | expect_s3_class(ggmice(dat, ggplot2::aes(bmi)), "ggplot") 13 | expect_s3_class(ggmice(imp, ggplot2::aes(bmi)), "ggplot") 14 | expect_s3_class(ggmice(dat, ggplot2::aes(y = bmi)), "ggplot") 15 | expect_s3_class(ggmice(imp, ggplot2::aes(y = bmi)), "ggplot") 16 | }) 17 | 18 | test_that("categorical data plot", { 19 | expect_s3_class(ggmice(dat, ggplot2::aes(hyp)), "ggplot") 20 | expect_s3_class(ggmice(imp, ggplot2::aes(hyp)), "ggplot") 21 | expect_s3_class(ggmice(dat, ggplot2::aes(age2)), "ggplot") 22 | expect_s3_class(ggmice(imp, ggplot2::aes(age2)), "ggplot") 23 | }) 24 | 25 | test_that("mixed data plot", { 26 | expect_s3_class(ggmice(dat, ggplot2::aes(age, bmi)), "ggplot") 27 | expect_s3_class(ggmice(imp, ggplot2::aes(age, bmi)), "ggplot") 28 | expect_s3_class(ggmice(dat, ggplot2::aes(age, hyp)), "ggplot") 29 | expect_s3_class(ggmice(imp, ggplot2::aes(age, hyp)), "ggplot") 30 | expect_s3_class(ggmice(dat, ggplot2::aes(age, age2)), "ggplot") 31 | expect_s3_class(ggmice(imp, ggplot2::aes(age, age2)), "ggplot") 32 | }) 33 | 34 | test_that("complete data plot", { 35 | expect_s3_class(ggmice(na.omit(dat), ggplot2::aes(bmi)), "ggplot") 36 | imp2 <- 37 | suppressWarnings(mice::mice(na.omit(dat), printFlag = FALSE, seed = 1)) 38 | expect_s3_class(ggmice(imp2, ggplot2::aes(bmi)), "ggplot") 39 | }) 40 | 41 | test_that("incorrect data", { 42 | expect_error(ggmice(NA)) 43 | expect_error(ggmice("test")) 44 | expect_error(ggmice(as.matrix(dat))) 45 | expect_error(ggmice(cbind(dat, dat), ggplot2::aes(bmi))) 46 | }) 47 | 48 | test_that("advanced mapping", { 49 | expect_error(ggmice(dat, ggplot2::aes(log(age)))) 50 | expect_error(ggmice(dat, ggplot2::aes(age3))) 51 | expect_warning(ggmice(dat, ggplot2::aes(bmi, color = bmi))) 52 | }) 53 | 54 | test_that("incorrect mapping", { 55 | expect_error(ggmice(dat)) 56 | expect_error(ggmice(dat, ggplot2::aes(x = test))) 57 | expect_error(ggmice(dat, ggplot2::aes(group = age))) 58 | expect_error(ggmice(dat, ggplot2::aes("bmi"))) 59 | }) 60 | -------------------------------------------------------------------------------- /tests/testthat/test-old_friends.R: -------------------------------------------------------------------------------- 1 | # create test objects 2 | imp <- mice::mice(mice::nhanes, printFlag = FALSE) 3 | 4 | # tests 5 | test_that("set of old friends functions generate message", { 6 | expect_message(bwplot(imp)) 7 | expect_message(densityplot(imp)) 8 | expect_message(stripplot(imp)) 9 | expect_message(xyplot(imp, bmi ~ age)) 10 | }) 11 | 12 | test_that("set of old friends functions generate plot", { 13 | expect_s3_class(bwplot(imp), "trellis") 14 | expect_s3_class(densityplot(imp), "trellis") 15 | expect_s3_class(stripplot(imp), "trellis") 16 | expect_s3_class(xyplot(imp, bmi ~ age), "trellis") 17 | }) 18 | -------------------------------------------------------------------------------- /tests/testthat/test-plot_corr.R: -------------------------------------------------------------------------------- 1 | # create test objects 2 | dat <- mice::nhanes 3 | 4 | # tests 5 | test_that("plot_corr creates ggplot object", { 6 | expect_s3_class(plot_corr(dat), "ggplot") 7 | expect_s3_class(plot_corr( 8 | dat, 9 | label = TRUE, 10 | square = FALSE, 11 | diagonal = TRUE, 12 | rotate = TRUE 13 | ), 14 | "ggplot") 15 | }) 16 | 17 | test_that("plot_corr takes non-default input arguments", { 18 | expect_s3_class(plot_corr(dat, c("age", "bmi")), "ggplot") 19 | expect_s3_class(plot_corr(dat, c(age, bmi)), "ggplot") 20 | expect_s3_class(plot_corr(cbind(dat, "with space" = stats::rnorm(nrow( 21 | dat 22 | )))), "ggplot") 23 | }) 24 | 25 | test_that("plot_corr returns error with incorrect argument(s)", { 26 | expect_error(plot_corr(data = "test")) 27 | expect_error(plot_corr(dat, vrb = "test")) 28 | expect_error(plot_corr(dat, age)) 29 | }) 30 | -------------------------------------------------------------------------------- /tests/testthat/test-plot_flux.R: -------------------------------------------------------------------------------- 1 | # create test objects 2 | dat <- mice::nhanes 3 | 4 | # tests 5 | test_that("plot_flux creates ggplot object", { 6 | expect_s3_class(plot_flux(dat), "ggplot") 7 | expect_s3_class(plot_flux(dat, label = FALSE, caption = FALSE), "ggplot") 8 | }) 9 | 10 | test_that("plot_flux works with different inputs", { 11 | expect_s3_class(plot_flux(dat, c("age", "bmi")), "ggplot") 12 | expect_s3_class(plot_flux(na.omit(dat)), "ggplot") 13 | expect_s3_class(plot_flux(cbind(dat, "with space" = NA)), "ggplot") 14 | }) 15 | 16 | test_that("plot_flux returns error with incorrect argument(s)", { 17 | expect_error(plot_flux(dat, vrb = "test")) 18 | }) 19 | -------------------------------------------------------------------------------- /tests/testthat/test-plot_pattern.R: -------------------------------------------------------------------------------- 1 | # create test objects 2 | dat <- mice::nhanes 3 | 4 | # tests 5 | test_that("plot_pattern produces plot", { 6 | expect_s3_class(plot_pattern(dat), "ggplot") 7 | expect_s3_class(plot_pattern(dat, square = FALSE, rotate = TRUE, cluster = "age", npat = 2), "ggplot") 8 | expect_s3_class(plot_pattern(cbind(dat, "testvar" = NA), caption = FALSE), "ggplot") 9 | }) 10 | 11 | test_that("plot_pattern works with different inputs", { 12 | expect_s3_class(plot_pattern(dat, c("age", "bmi")), "ggplot") 13 | expect_s3_class(plot_pattern(dat, c(age, bmi)), "ggplot") 14 | expect_s3_class(plot_pattern(data.frame(age = dat$age, testvar = NA)), "ggplot") 15 | expect_s3_class(plot_pattern(cbind(dat, "with space" = NA)), "ggplot") 16 | }) 17 | 18 | 19 | test_that("plot_pattern with incorrect argument(s)", { 20 | expect_output(plot_pattern(na.omit(dat))) 21 | expect_error(plot_pattern("test")) 22 | expect_error(plot_pattern(dat, vrb = "test")) 23 | expect_error(plot_pattern(dat, cluster = "test")) 24 | expect_error(plot_pattern(cbind(dat, .x = NA))) 25 | expect_error(plot_pattern(dat, npat = "test")) 26 | }) 27 | -------------------------------------------------------------------------------- /tests/testthat/test-plot_pred.R: -------------------------------------------------------------------------------- 1 | # create test objects 2 | dat <- mice::nhanes 3 | pred <- mice::quickpred(dat) 4 | 5 | # tests 6 | test_that("plot_pred creates ggplot object", { 7 | expect_s3_class(plot_pred(pred), "ggplot") 8 | expect_s3_class(plot_pred( 9 | pred, 10 | method = c("pmm"), 11 | label = FALSE, 12 | square = FALSE, 13 | rotate = TRUE 14 | ), 15 | "ggplot") 16 | expect_s3_class(plot_pred(pred, vrb = c("age", "bmi")), "ggplot") 17 | expect_s3_class(plot_pred(pred, vrb = c(age, bmi)), "ggplot") 18 | expect_s3_class(plot_pred(rbind( 19 | cbind(pred, "with space" = 0), "with space" = 0 20 | )), "ggplot") 21 | }) 22 | 23 | test_that("plot_pred with incorrect argument(s)", { 24 | expect_error(plot_pred(dat)) 25 | }) 26 | -------------------------------------------------------------------------------- /tests/testthat/test-plot_trace.R: -------------------------------------------------------------------------------- 1 | # create test objects 2 | dat <- mice::nhanes 3 | imp <- mice::mice(dat, printFlag = FALSE) 4 | v <- c("bmi", "hyp") 5 | 6 | # tests 7 | test_that("plot_trace creates ggplot object", { 8 | expect_s3_class(plot_trace(imp), "ggplot") 9 | expect_s3_class(plot_trace(imp, vrb = "bmi"), "ggplot") 10 | expect_s3_class(plot_trace(imp, vrb = c("bmi", "hyp")), "ggplot") 11 | expect_s3_class(plot_trace(imp, vrb = "all"), "ggplot") 12 | expect_s3_class(plot_trace(imp, vrb = bmi), "ggplot") 13 | expect_s3_class(plot_trace(imp, vrb = c("bmi", "hyp")), "ggplot") 14 | expect_s3_class(plot_trace(imp, vrb = c(bmi, hyp)), "ggplot") 15 | expect_s3_class(plot_trace(imp, vrb = !!v), "ggplot") 16 | expect_s3_class(plot_trace(imp, vrb = !!v[1]), "ggplot") 17 | }) 18 | 19 | test_that("plot_trace returns error with incorrect argument(s)", { 20 | expect_error(plot_trace(dat)) 21 | expect_error(plot_trace(imp, vrb = "test")) 22 | expect_error(plot_trace(imp, vrb = "age")) 23 | expect_message(plot_trace(imp, vrb = c("age", "bmi"))) 24 | expect_error(plot_trace(imp, vrb = v)) 25 | expect_error(plot_trace(imp, vrb = v[1])) 26 | }) 27 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/ggmice.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Get started" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{ggmice} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | %\VignetteDepends{mice} 9 | %\VignetteDepends{ggplot2} 10 | --- 11 | 12 | ```{r, include = FALSE} 13 | knitr::opts_chunk$set( 14 | collapse = TRUE, 15 | comment = "#>", 16 | fig.width = 7.2, 17 | fig.height = 4 18 | ) 19 | options(rmarkdown.html_vignette.check_title = FALSE) 20 | ``` 21 | 22 | # The `ggmice` package 23 | 24 | The `ggmice` package provides visualizations for the evaluation of incomplete data, `mice` imputation model arguments, and multiply imputed data sets (`mice::mids` objects). The functions in `ggmice` adhere to the 'grammar of graphics' philosophy, popularized by the `ggplot2` package. With that, `ggmice` enhances imputation workflows and provides plotting objects that are easily extended and manipulated by each individual 'imputer'. 25 | 26 | This vignette gives an overview of the different plotting function in `ggmice`. The core function, `ggmice()`, is a `ggplot2::ggplot()` wrapper function which handles missing and imputed values. In this vignette, you'll learn how to create and interpret `ggmice` visualizations. 27 | 28 | Experienced `mice` users may already be familiar with the `lattice` style plotting functions in `mice`. These 'old friends' such as `mice::bwplot()` can be re-created with the `ggmice()` function, see the [Old friends](https://amices.org/ggmice/articles/old_friends.html) vignette for advice. 29 | 30 | 31 | 32 | 33 | # Set-up 34 | 35 | You can install the latest `ggmice` release from [CRAN](https://CRAN.R-project.org/package=ggmice) with: 36 | 37 | ``` r 38 | install.packages("ggmice") 39 | ``` 40 | 41 | The development version of the `ggmice` package can be installed from GitHub with: 42 | 43 | ``` r 44 | # install.packages("devtools") 45 | devtools::install_github("amices/ggmice") 46 | ``` 47 | 48 | After installing `ggmice`, you can load the package into your `R` workspace. It is highly recommended to load the `mice` and `ggplot2` packages as well. This vignette assumes that all three packages are loaded: 49 | 50 | ```{r setup, warning = FALSE, message = FALSE} 51 | library(mice) 52 | library(ggplot2) 53 | library(ggmice) 54 | ``` 55 | 56 | We will use the `mice::boys` data for illustrations. This is an incomplete dataset ($n = 748$) with cross-sectional data on $9$ growth-related variables (e.g., age in years and height in cm). 57 | 58 | We load the incomplete data with: 59 | 60 | ```{r data} 61 | dat <- boys 62 | ``` 63 | 64 | For the purpose of this vignette, we impute all incomplete variables $m = 3$ times with predictive mean matching as imputation method. Imputations are generated with: 65 | 66 | ```{r imp, results = "hide"} 67 | imp <- mice(dat, m = 3, method = "pmm") 68 | ``` 69 | 70 | We now have the necessary packages, an incomplete dataset (`dat`), and a `mice::mids` object (`imp`) loaded in our workspace. 71 | 72 | 73 | # The `ggmice()` function 74 | 75 | The core function in the `ggmice` package is `ggmice()`. This function mimics how the `ggplot2` function `ggplot()` works: both take a `data` argument and a `mapping` argument, and will return an object of class `ggplot`. 76 | 77 | Using `ggmice()` looks equivalent to a `ggplot()` call: 78 | 79 | ```{r gg, eval=FALSE} 80 | ggplot(dat, aes(x = age)) 81 | ggmice(dat, aes(x = age)) 82 | ``` 83 | 84 | The main difference between the two functions is that `ggmice()` is actually a wrapper around `ggplot()`, including some pre-processing steps for incomplete and imputed data. Because of the internal processing in `ggmice()`, the `mapping` argument is *required* for each `ggmice()` call. This is in contrast to the aesthetic mapping in `ggplot()`, which may also be provided in subsequent plotting layers. After creating a `ggplot` object, any desired plotting layers may be added (e.g., with the family of `ggplot2::geom_*` functions), or adjusted (e.g., with the `ggplot2::labs()` function). This makes `ggmice()` a versatile plotting function for incomplete and/or imputed data. 85 | 86 | The object supplied to the `data` argument in `ggmice()` should be an incomplete dataset of class `data.frame`, or an imputation object of class `mice::mids`. Depending on which one of these is provided, the resulting visualization will either differentiate between observed and *missing* data, or between observed and *imputed* data. By convention, observed data is plotted in blue and missing or imputed data is plotted in red. 87 | 88 | The `mapping` argument in `ggmice()` cannot be empty. An `x` or `y` mapping (or both) has to be supplied for `ggmice()` to function. This aesthetic mapping can be provided with the `ggplot2` function `aes()` (or equivalents). Other mapping may be provided too, except for `colour`, which is already used to display observed versus missing or imputed data. 89 | 90 | 91 | ## Incomplete data 92 | 93 | If the object supplied to the `data` argument in `ggmice()` is a `data.frame`, the visualization will contain observed data in blue and missing data in red. Since missing data points are by definition unobserved, the values themselves cannot be plotted. What we *can* plot are sets of variable pairs. Any missing values in one variable can be displayed on the axis of the other. This provides a visual cue that the missing data is distinct from the observed values, but still displays the observed value of the other variable. 94 | 95 | For example, the variable `age` is completely observed, while there are some missing entries for the height variable `hgt`. We can create a scatter plot of these two variables with: 96 | 97 | ```{r inc-con} 98 | ggmice(dat, aes(age, hgt)) + 99 | geom_point() 100 | ``` 101 | 102 | The `age` of cases with missing `hgt` are plotted on the horizontal axis. This is in contrast to a regular `ggplot()` call with the same arguments, which would leave out all cases with missing `hgt`. So, with `ggmice()` we loose less information, and may even gain valuable insight into the missingness in the data. 103 | 104 | Another example of `ggmice()` in action on incomplete data is when one of the variables is categorical. The incomplete continuous variable `hgt` is plotted against the incomplete categorical variable `reg` with: 105 | 106 | ```{r inc-cat} 107 | ggmice(dat, aes(reg, hgt)) + 108 | geom_point() 109 | ``` 110 | 111 | Again, missing values are plotted on the axes. Cases with observed `hgt` and missing `reg` are plotted on the vertical axis. Cases with observed `reg` and missing `hgt` are plotted on the horizontal axis. There are no cases were neither is observed, but otherwise these would be plotted on the intersection of the two axes. 112 | 113 | The 'grammar of graphics' makes it easy to adjust the plots programmatically. For example, we could be interested in the differences in growth data between the city and other regions. Add facets based on a clustering variable with: 114 | 115 | ```{r inc-clus} 116 | ggmice(dat, aes(wgt, hgt)) + 117 | geom_point() + 118 | facet_wrap(~ reg == "city", labeller = label_both) 119 | ``` 120 | 121 | Or, alternatively, we could convert the plotted values of the variable `hgt` from centimeters to inches and the variable `wgt` from kilograms to pounds with: 122 | 123 | ```{r inc-trans} 124 | ggmice(dat, aes(wgt * 2.20, hgt / 2.54)) + 125 | geom_point() + 126 | labs(x = "Weight (lbs)", y = "Height (in)") 127 | ``` 128 | 129 | A final example of `ggmice()` applied to incomplete data is faceting based on a missingness indicator. Doing so may help explore the missingness mechanisms in the incomplete data. The distribution of the continuous variable `age` and categorical variable `reg` are visualized faceted by the missingness indicator for `hgt` with: 130 | 131 | ```{r} 132 | # continuous variable 133 | ggmice(dat, aes(age)) + 134 | geom_density() + 135 | facet_wrap(~ factor(is.na(hgt) == 0, labels = c("observed height", "missing height"))) 136 | # categorical variable 137 | ggmice(dat, aes(reg)) + 138 | geom_bar(fill = "white") + 139 | facet_wrap(~ factor(is.na(hgt) == 0, labels = c("observed height", "missing height"))) 140 | ``` 141 | 142 | 143 | ## Imputed data 144 | 145 | If the `data` argument in `ggmice()` is provided a `mice::mids` object, the resulting plot will contain observed data in blue and imputed data in red. There are many possible visualizations for imputed data, four of which are explicitly defined in the `mice` package. Each of these can be re-created with the `ggmice()` function (see the [Old friends](https://amices.org/ggmice/articles/old_friends.html) vignette). But `ggmice()` can do even more. 146 | 147 | For example, we could create the same scatter plots as the ones above, but now on the imputed data: 148 | 149 | ```{r imp-same} 150 | ggmice(imp, aes(age, hgt)) + 151 | geom_point() 152 | ggmice(imp, aes(reg, hgt)) + 153 | geom_point() 154 | ggmice(imp, aes(wgt, hgt)) + 155 | geom_point() + 156 | facet_wrap(~ reg == "city", labeller = label_both) 157 | ggmice(imp, aes(wgt * 2.20, hgt / 2.54)) + 158 | geom_point() + 159 | labs(x = "Weight (lbs)", y = "Height (in)") 160 | ``` 161 | 162 | These figures show the observed data points once in blue, plus three imputed values in red for each missing entry. 163 | 164 | It is also possible to use the imputation number as mapping variable in the plot. For example, we can create a stripplot of observed and imputed data with the imputation number `.imp` on the horizontal axis: 165 | 166 | ```{r imp-strip} 167 | ggmice(imp, aes(x = .imp, y = hgt)) + 168 | geom_jitter(height = 0, width = 0.25) + 169 | labs(x = "Imputation number") 170 | ``` 171 | 172 | A major advantage of `ggmice()` over the equivalent function `mice::stripplot()` is that `ggmice` allows us to add subsequent plotting layers, such as a boxplot overlay: 173 | 174 | ```{r imp-box} 175 | ggmice(imp, aes(x = .imp, y = hgt)) + 176 | geom_jitter(height = 0, width = 0.25) + 177 | geom_boxplot(width = 0.5, size = 1, alpha = 0.75, outlier.shape = NA) + 178 | labs(x = "Imputation number") 179 | ``` 180 | 181 | You may want to create a plot visualizing the imputations of multiple variables as one object. This can be done by combining `ggmice` with the functional programming package `purrr` and visualization package `patchwork`. For example, we could obtain boxplots of different imputed variables as one object using: 182 | 183 | ```{r facet} 184 | purrr::map(c("wgt", "hgt", "bmi"), ~ { 185 | ggmice(imp, aes(x = .imp, y = .data[[.x]])) + 186 | geom_boxplot() + 187 | labs(x = "Imputation number") 188 | }) %>% 189 | patchwork::wrap_plots() 190 | ``` 191 | 192 | To re-create any `mice` plot with `ggmice`, see the [Old friends](https://amices.org/ggmice/articles/old_friends.html) vignette. 193 | 194 | 195 | # Other functions 196 | 197 | The `ggmice` package contains some additional plotting functions to explore incomplete data and evaluate convergence of the imputation algorithm. These are presented in the order of a typical imputation workflow, where the missingness is first investigated using a missing data pattern and influx-outflux plot, then imputation models are built based on relations between variables, and finally the imputations are inspected visually to check for non-convergence. 198 | 199 | ## Missing data pattern 200 | 201 | The `plot_pattern()` function displays the missing data pattern in an incomplete dataset. The argument `data` (the incomplete dataset) is required, the argument `square` is optional and determines whether the missing data pattern has square or rectangular tiles, and the optional argument `rotate` changes the angle of the variable names 90 degrees if requested. Other optional arguments are `cluster` and `npat`. 202 | 203 | ```{r pattern} 204 | # create missing data pattern plot 205 | plot_pattern(dat) 206 | 207 | # specify optional arguments 208 | plot_pattern( 209 | dat, 210 | square = TRUE, 211 | rotate = TRUE, 212 | npat = 3, 213 | cluster = "reg" 214 | ) 215 | ``` 216 | 217 | ## Influx and outflux 218 | 219 | The `plot_flux()` function produces an influx-outflux plot. The influx of a variable quantifies how well its missing data connect to the observed data on other variables. The outflux of a variable quantifies how well its observed data connect to the missing data on other variables. In general, higher influx and outflux values are preferred when building imputation models. The plotting function requires an incomplete dataset (argument `data`), and takes optional arguments to adjust the legend and axis labels. 220 | 221 | ```{r flux} 222 | # create influx-outflux plot 223 | plot_flux(dat) 224 | 225 | # specify optional arguments 226 | plot_flux( 227 | dat, 228 | label = FALSE, 229 | caption = FALSE 230 | ) 231 | ``` 232 | 233 | 234 | ## Correlations between variables 235 | 236 | The function `plot_corr()` can be used to investigate relations between variables, for the development of imputation models. Only one of the arguments (`data`, the incomplete dataset) is required, all other arguments are optional. 237 | 238 | ```{r correlations} 239 | # create correlation plot 240 | plot_corr(dat) 241 | 242 | # specify optional arguments 243 | plot_corr( 244 | dat, 245 | vrb = c("hgt", "wgt", "bmi"), 246 | label = TRUE, 247 | square = FALSE, 248 | diagonal = TRUE, 249 | rotate = TRUE 250 | ) 251 | ``` 252 | 253 | ## Predictor matrix 254 | 255 | The function `plot_pred()` displays `mice` predictor matrices. A predictor matrix is typically created using `mice::make.predictorMatrix()`, `mice::quickpred()`, or by using the default in `mice::mice()` and extracting the `predictorMatrix` from the resulting `mids` object. The `plot_pred()` function requires a predictor matrix (the `data` argument), but other arguments can be provided too. 256 | 257 | ```{r predictormatrix} 258 | # create predictor matrix 259 | pred <- quickpred(dat) 260 | 261 | # create predictor matrix plot 262 | plot_pred(pred) 263 | 264 | # specify optional arguments 265 | plot_pred( 266 | pred, 267 | label = FALSE, 268 | square = FALSE, 269 | rotate = TRUE, 270 | method = "pmm" 271 | ) 272 | ``` 273 | 274 | 275 | ## Algorithmic convergence 276 | 277 | The function `plot_trace()` plots the trace lines of the MICE algorithm for convergence evaluation. The only required argument is `data` (to supply a `mice::mids` object). The optional argument `vrb` defaults to `"all"`, which would display traceplots for all variables. 278 | 279 | ```{r convergence} 280 | # create traceplot for one variable 281 | plot_trace(imp, "hgt") 282 | ``` 283 | 284 | 285 | --- 286 | 287 | # 288 | 289 | This is the end of the vignette. This document was generated using: 290 | 291 | ```{r session, class.source = 'fold-hide'} 292 | sessionInfo() 293 | ``` 294 | -------------------------------------------------------------------------------- /vignettes/old_friends.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Old friends" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{old_friends} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | # Create the `ggmice` equivalent of `mice` plots 10 | 11 | How to re-create the output of the plotting functions from `mice` with `ggmice`. In alphabetical order of the `mice` functions. 12 | 13 | ```{r, include = FALSE} 14 | knitr::opts_chunk$set( 15 | collapse = TRUE, 16 | comment = "#>", 17 | fig.width = 7.2, 18 | fig.height = 4, 19 | warning = FALSE, 20 | message = FALSE 21 | ) 22 | options(rmarkdown.html_vignette.check_title = FALSE) 23 | ``` 24 | 25 | First load the `ggmice`, `mice`, and `ggplot2` packages, some incomplete data and a `mids` object into your workspace. 26 | 27 | ```{r setup, warning = FALSE, message = FALSE} 28 | # load packages 29 | library(ggmice) 30 | library(mice) 31 | library(ggplot2) 32 | # load incomplete dataset from mice 33 | dat <- boys 34 | # generate imputations 35 | imp <- mice(dat, method = "pmm", printFlag = FALSE) 36 | ``` 37 | 38 | 39 | # `bwplot` 40 | 41 | Box-and-whisker plot of observed and imputed data. 42 | 43 | ```{r bwplot} 44 | # original plot 45 | mice::bwplot(imp, hgt ~ .imp) 46 | # ggmice equivalent 47 | ggmice(imp, aes(x = .imp, y = hgt)) + 48 | geom_boxplot() + 49 | labs(x = "Imputation number") 50 | # extended reproduction with ggmice 51 | ggmice(imp, aes(x = .imp, y = hgt)) + 52 | stat_boxplot(geom = "errorbar", linetype = "dashed") + 53 | geom_boxplot(outlier.colour = "grey", outlier.shape = 1) + 54 | labs(x = "Imputation number") + 55 | theme(legend.position = "none") 56 | ``` 57 | 58 | 59 | # `densityplot` 60 | 61 | Density plot of observed and imputed data. 62 | 63 | ```{r densityplot} 64 | # original plot 65 | mice::densityplot(imp, ~hgt) 66 | # ggmice equivalent 67 | ggmice(imp, aes(x = hgt, group = .imp)) + 68 | geom_density() 69 | # extended reproduction with ggmice 70 | ggmice(imp, aes(x = hgt, group = .imp, size = .where)) + 71 | geom_density() + 72 | scale_size_manual( 73 | values = c("observed" = 1, "imputed" = 0.5), 74 | guide = "none" 75 | ) + 76 | theme(legend.position = "none") 77 | ``` 78 | 79 | # `fluxplot` 80 | 81 | Influx and outflux plot of multivariate missing data patterns. 82 | 83 | ```{r flux} 84 | # original plot 85 | fluxplot(dat) 86 | # ggmice equivalent 87 | plot_flux(dat) 88 | ``` 89 | 90 | 91 | # `md.pattern` 92 | 93 | Missing data pattern plot. 94 | 95 | ```{r md.pattern} 96 | # original plot 97 | md <- md.pattern(dat) 98 | # ggmice equivalent 99 | plot_pattern(dat) 100 | # extended reproduction with ggmice 101 | plot_pattern(dat, square = TRUE) + 102 | theme( 103 | legend.position = "none", 104 | axis.title = element_blank(), 105 | axis.title.x.top = element_blank(), 106 | axis.title.y.right = element_blank() 107 | ) 108 | ``` 109 | 110 | # `plot.mids` 111 | 112 | Plot the trace lines of the MICE algorithm. 113 | 114 | ```{r plot.mids} 115 | # original plot 116 | plot(imp, hgt ~ .it | .ms) 117 | # ggmice equivalent 118 | plot_trace(imp, "hgt") 119 | ``` 120 | 121 | # `stripplot` 122 | 123 | Stripplot of observed and imputed data. 124 | 125 | ```{r stripplot} 126 | # original plot 127 | mice::stripplot(imp, hgt ~ .imp) 128 | # ggmice equivalent 129 | ggmice(imp, aes(x = .imp, y = hgt)) + 130 | geom_jitter(width = 0.25) + 131 | labs(x = "Imputation number") 132 | # extended reproduction with ggmice (not recommended) 133 | ggmice(imp, aes(x = .imp, y = hgt)) + 134 | geom_jitter( 135 | shape = 1, 136 | width = 0.1, 137 | na.rm = TRUE, 138 | data = data.frame( 139 | hgt = dat$hgt, 140 | .imp = factor(rep(1:imp$m, each = nrow(dat))), 141 | .where = "observed" 142 | ) 143 | ) + 144 | geom_jitter(shape = 1, width = 0.1) + 145 | labs(x = "Imputation number") + 146 | theme(legend.position = "none") 147 | ``` 148 | 149 | 150 | # `xyplot` 151 | 152 | Scatterplot of observed and imputed data. 153 | 154 | ```{r} 155 | # original plot 156 | mice::xyplot(imp, hgt ~ age) 157 | # ggmice equivalent 158 | ggmice(imp, aes(age, hgt)) + 159 | geom_point() 160 | # extended reproduction with ggmice 161 | ggmice(imp, aes(age, hgt)) + 162 | geom_point(size = 2, shape = 1) + 163 | theme(legend.position = "none") 164 | ``` 165 | 166 | # Extensions 167 | 168 | ## Interactive plots 169 | 170 | To make `ggmice` visualizations interactive, the `plotly` package can be used. For example, an interactive influx and outflux plot may be more legible than a static one. 171 | 172 | ```{r plotly} 173 | # load packages 174 | library(plotly) 175 | # influx and outflux plot 176 | p <- plot_flux(dat) 177 | ggplotly(p) 178 | ``` 179 | 180 | ## Plot multiple variables 181 | 182 | You may want to create a plot visualizing the imputations of multiple variables as one object. To visualize multiple variables at once, the variable names are saved in a vector. This vector is used together with the functional programming package `purrr` and visualization package `patchwork` to `map()` over the variables and subsequently `wrap_plots` to create a single figure. 183 | 184 | ```{r mapping} 185 | # load packages 186 | library(purrr) 187 | library(patchwork) 188 | # create vector with variable names 189 | vrb <- names(dat) 190 | ``` 191 | 192 | Display box-and-whisker plots for all variables. 193 | 194 | ```{r bwplots} 195 | # original plot 196 | mice::bwplot(imp) 197 | # ggmice equivalent 198 | p <- map(vrb, ~ { 199 | ggmice(imp, aes(x = .imp, y = .data[[.x]])) + 200 | geom_boxplot() + 201 | scale_x_discrete(drop = FALSE) + 202 | labs(x = "Imputation number") 203 | }) 204 | wrap_plots(p, guides = "collect") & 205 | theme(legend.position = "bottom") 206 | ``` 207 | 208 | Display density plots for all variables. 209 | 210 | ```{r densityplots, message=FALSE, warning=FALSE} 211 | # original plot 212 | mice::densityplot(imp) 213 | # ggmice equivalent 214 | p <- map(vrb, ~ { 215 | ggmice(imp, aes(x = .data[[.x]], group = .imp)) + 216 | geom_density() 217 | }) 218 | wrap_plots(p, guides = "collect") & 219 | theme(legend.position = "bottom") 220 | ``` 221 | 222 | Display strip plots for all variables. 223 | 224 | ```{r stripplots} 225 | # original plot 226 | mice::stripplot(imp) 227 | # ggmice equivalent 228 | p <- map(vrb, ~ { 229 | ggmice(imp, aes(x = .imp, y = .data[[.x]])) + 230 | geom_jitter() + 231 | labs(x = "Imputation number") 232 | }) 233 | wrap_plots(p, guides = "collect") & 234 | theme(legend.position = "bottom") 235 | ``` 236 | 237 | --- 238 | 239 | # 240 | 241 | This is the end of the vignette. This document was generated using: 242 | 243 | ```{r session, class.source = 'fold-hide'} 244 | sessionInfo() 245 | ``` 246 | --------------------------------------------------------------------------------