├── .Rbuildignore
├── .gitignore
├── .travis.yml
├── DESCRIPTION
├── LICENSE
├── LICENSE.md
├── NAMESPACE
├── R
├── glances.R
├── mputr-package.R
├── nobs.R
├── tidiers.R
└── utils.R
├── README.Rmd
├── README.md
├── appveyor.yml
├── inst
└── explore.Rmd
├── man
├── glance.melded.Rd
├── mputr.Rd
├── nobs.melded.Rd
├── pipe.Rd
├── reexports.Rd
└── tidy.melded.Rd
└── mputr.Rproj
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^README\.Rmd$
4 | ^LICENSE\.md$
5 | ^\.travis\.yml$
6 | ^appveyor\.yml$
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | inst/doc
2 | .Rproj.user
3 | .Rhistory
4 | .RData
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r
2 |
3 | language: R
4 | cache: packages
5 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: mputr
2 | Title: Tidy Approaches for Multiple Imputation
3 | Version: 0.0.0.9000
4 | Authors@R: c(
5 | person(given = "Nicholas",
6 | family = "Tierney",
7 | email = "nicholas.tierney@gmail.com",
8 | role = c("aut", "cre"),
9 | comment = c(ORCID = "https://orcid.org/0000-0003-1460-8722")),
10 | person(given = "Andrew",
11 | family = "Heiss",
12 | role = c("aut"),
13 | email = "andrew@andrewheiss.com",
14 | comment = c(ORCID = "0000-0002-3948-3914"))
15 | )
16 | Description: An experimental package to provide broom tidier functions for
17 | multiply imputed data.
18 | Depends: R (>= 3.5)
19 | License: MIT + file LICENSE
20 | Encoding: UTF-8
21 | LazyData: true
22 | Suggests:
23 | knitr,
24 | rmarkdown
25 | VignetteBuilder: knitr
26 | Imports:
27 | purrr,
28 | dplyr,
29 | tidyr,
30 | Amelia,
31 | broom,
32 | generics,
33 | magrittr,
34 | stats,
35 | tibble,
36 | forcats
37 | RoxygenNote: 6.1.1
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2019
2 | COPYRIGHT HOLDER: Nicholas Tierney
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2019 Nicholas Tierney
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | S3method(glance,melded)
4 | S3method(nobs,melded)
5 | S3method(tidy,melded)
6 | export("%>%")
7 | export(augment)
8 | export(glance)
9 | export(tidy)
10 | importFrom(generics,augment)
11 | importFrom(generics,glance)
12 | importFrom(generics,tidy)
13 | importFrom(magrittr,"%>%")
14 | importFrom(stats,nobs)
15 |
--------------------------------------------------------------------------------
/R/glances.R:
--------------------------------------------------------------------------------
1 | #' Summarise Amelia's multiple imputations
2 | #'
3 | #' A broom glance summary for multiple imputations from Andrew's blog post:
4 | #' https://www.andrewheiss.com/blog/2018/03/07/amelia-tidy-melding/
5 | #' Andrews note: This means properly melded parameters and the simple average
6 | #' of the parameters of these models are roughly the same sake of simplicty
7 | #' we just take the average here.
8 | #'
9 | #' @param x Amelia melded imputed data
10 | #' @param ... other arguments passed to methods
11 | #'
12 | #' @return one line dataframe summary of the multiply imputed data
13 | #' @export
14 | glance.melded <- function(x, ...) {
15 | output <- tibble::tibble(models = x) %>%
16 | dplyr::mutate(glance = models %>% purrr::map(broom::glance)) %>%
17 | tidyr::unnest(glance) %>%
18 | dplyr::summarise_at(.vars = dplyr::vars(r.squared,
19 | adj.r.squared,
20 | sigma,
21 | statistic,
22 | p.value,
23 | df,
24 | logLik,
25 | AIC,
26 | BIC,
27 | deviance,
28 | df.residual),
29 | .funs = list(mean = mean)) %>%
30 | dplyr::mutate(m = as.integer(length(x)))
31 |
32 | # glance objects only have a data.frame class, not tbl_df or anything else
33 | class(output) <- "data.frame"
34 | output
35 | }
36 |
--------------------------------------------------------------------------------
/R/mputr-package.R:
--------------------------------------------------------------------------------
1 | #' mputr
2 | #'
3 | #' @name mputr
4 | #' @docType package
5 | NULL
6 |
7 | if(getRversion() >= "2.15.1") utils::globalVariables(c("."))
8 | globalVariables(c("AIC",
9 | "BIC",
10 | "key",
11 | "r.squared",
12 | "adj.r.squared",
13 | "tidied",
14 | "statistic",
15 | "std.error",
16 | "value",
17 | "m",
18 | "term",
19 | "estimate",
20 | "models",
21 | "p.value",
22 | "deviance",
23 | "df",
24 | "df.residual",
25 | "logLik",
26 | "sigma"))
27 |
--------------------------------------------------------------------------------
/R/nobs.R:
--------------------------------------------------------------------------------
1 | #' Take the number of observations from the first Amelia melded model
2 | #'
3 | #' @param object Amelia melded model
4 | #' @param ... other options to pass to `nobs`
5 | #'
6 | #' @return integer
7 | #' @importFrom stats nobs
8 | #' @method nobs melded
9 | #' @export
10 | nobs.melded <- function(object, ...) {
11 | stats::nobs(object[[1]])
12 | }
13 |
--------------------------------------------------------------------------------
/R/tidiers.R:
--------------------------------------------------------------------------------
1 | #' Tidy summaries for melded data
2 | #'
3 | #' This is an approach for tidying Amelia imputed dataframes from Andrew Heiss
4 | #'
5 | #'
6 | #' @param x melded object from Amelia
7 | #' @param ... other arguments passed to methods
8 | #' @param conf.int Return confidence intervals. Default is FALSE
9 | #' @param conf.level Confidence level (if confidence intervals are use).
10 | #' Default is 0.95.
11 | #'
12 | #' @return tidy dataframe with pooled estimates from imputed data
13 | #' @export
14 | tidy.melded <- function(x,
15 | ...,
16 | conf.int = FALSE,
17 | conf.level = 0.95) {
18 | # Get the df from one of the models
19 | model_degrees_freedom <- broom::glance(x[[1]])$df.residual
20 |
21 | # Create matrices of the estimates and standard errors
22 | params <- tibble::tibble(models = x) %>%
23 | dplyr::mutate(m = 1:dplyr::n(),
24 | tidied = models %>% purrr::map(tidy)) %>%
25 | tidyr::unnest(tidied) %>%
26 | dplyr::select(m,
27 | term,
28 | estimate,
29 | std.error) %>%
30 | tidyr::gather(key,
31 | value,
32 | estimate,
33 | std.error) %>%
34 | # Order the terms so that spread() keeps them in order
35 | dplyr::mutate(term = forcats::fct_inorder(term)) %>%
36 | tidyr::spread(term, value)
37 |
38 | just_coefs <- params %>%
39 | dplyr::filter(key == "estimate") %>%
40 | dplyr::select(-m, -key)
41 |
42 | just_ses <- params %>%
43 | dplyr::filter(key == "std.error") %>%
44 | dplyr::select(-m, -key)
45 |
46 | # Meld the coefficients with Rubin's rules
47 | coefs_melded <- Amelia::mi.meld(just_coefs, just_ses)
48 |
49 | # Create tidy output
50 | output <- as.data.frame(cbind(t(coefs_melded$q.mi),
51 | t(coefs_melded$se.mi))) %>%
52 | purrr::set_names(nm = c("estimate", "std.error")) %>%
53 | tibble::rownames_to_column(var = "term") %>%
54 | # dplyr::mutate(term = rownames(.)) %>%
55 | dplyr::select(term, dplyr::everything()) %>%
56 | dplyr::mutate(statistic = estimate / std.error,
57 | p.value = 2 * stats::pt(abs(statistic),
58 | model_degrees_freedom,
59 | lower.tail = FALSE))
60 |
61 | # Add confidence intervals if needed
62 | if (conf.int & conf.level) {
63 | # Convert conf.level to tail values (0.025 when it's 0.95)
64 | a <- (1 - conf.level) / 2
65 |
66 | output <- output %>%
67 | dplyr::mutate(
68 | conf.low = estimate + std.error * stats::qt(a, model_degrees_freedom),
69 | conf.high = estimate + std.error * stats::qt((1 - a), model_degrees_freedom)
70 | )
71 | }
72 |
73 | # tidy objects only have a data.frame class, not tbl_df or anything else
74 | class(output) <- "data.frame"
75 | output
76 | }
77 |
--------------------------------------------------------------------------------
/R/utils.R:
--------------------------------------------------------------------------------
1 | #' Pipe operator
2 | #'
3 | #' See \code{magrittr::\link[magrittr]{\%>\%}} for details.
4 | #'
5 | #' @name %>%
6 | #' @rdname pipe
7 | #' @keywords internal
8 | #' @export
9 | #' @importFrom magrittr %>%
10 | #' @usage lhs \%>\% rhs
11 | NULL
12 |
13 | #' @importFrom generics tidy
14 | #' @export
15 | generics::tidy
16 |
17 | #' @importFrom generics glance
18 | #' @export
19 | generics::glance
20 |
21 | #' @importFrom generics augment
22 | #' @export
23 | generics::augment
24 |
--------------------------------------------------------------------------------
/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 | # mputr
16 |
17 |
18 | [](https://www.tidyverse.org/lifecycle/#experimental)
19 | [](https://travis-ci.org/njtierney/mputr)
20 | [](https://ci.appveyor.com/project/njtierney/mputr)
21 |
22 |
23 | The goal of mputr is to make it easier to deal with multiple imputation.
24 |
25 | It is an **experimental package** that may end up being worked back into `naniar`.
26 |
27 | It's goals are to:
28 |
29 | * Provide broom tidiers for multiple imputation objects (based on Andrew Heiss's work [here](https://www.andrewheiss.com/blog/2018/03/07/amelia-tidy-melding/), and [here](https://www.andrewheiss.com/blog/2018/03/08/amelia-broom-huxtable/))
30 | * Provide helpers for exploring multiple imputations
31 | * Potentially provide an interface similar to `simputation`, but for multiple imputation.
32 |
33 |
34 | ## Installation
35 |
36 | ``` r
37 | # install.packages("remotes")
38 | remotes::install_github("njtierney/mputr")
39 | ```
40 | ]
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # mputr
5 |
6 |
7 |
8 | [](https://www.tidyverse.org/lifecycle/#experimental)
10 | [](https://travis-ci.org/njtierney/mputr)
12 | [](https://ci.appveyor.com/project/njtierney/mputr)
14 |
15 |
16 | The goal of mputr is to make it easier to deal with multiple imputation.
17 |
18 | It is an **experimental package** that may end up being worked back into
19 | `naniar`.
20 |
21 | It’s goals are to:
22 |
23 | - Provide broom tidiers for multiple imputation objects (based on
24 | Andrew Heiss’s work
25 | [here](https://www.andrewheiss.com/blog/2018/03/07/amelia-tidy-melding/),
26 | and
27 | [here](https://www.andrewheiss.com/blog/2018/03/08/amelia-broom-huxtable/))
28 | - Provide helpers for exploring multiple imputations
29 | - Potentially provide an interface similar to `simputation`, but for
30 | multiple imputation.
31 |
32 | ## Installation
33 |
34 | ``` r
35 | # install.packages("remotes")
36 | remotes::install_github("njtierney/mputr")
37 | ```
38 |
39 | \]
40 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # DO NOT CHANGE the "init" and "install" sections below
2 |
3 | # Download script file from GitHub
4 | init:
5 | ps: |
6 | $ErrorActionPreference = "Stop"
7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1"
8 | Import-Module '..\appveyor-tool.ps1'
9 |
10 | install:
11 | ps: Bootstrap
12 |
13 | cache:
14 | - C:\RLibrary
15 |
16 | environment:
17 | NOT_CRAN: true
18 | # env vars that may need to be set, at least temporarily, from time to time
19 | # see https://github.com/krlmlr/r-appveyor#readme for details
20 | # USE_RTOOLS: true
21 | # R_REMOTES_STANDALONE: true
22 |
23 | # Adapt as necessary starting from here
24 |
25 | build_script:
26 | - travis-tool.sh install_deps
27 |
28 | test_script:
29 | - travis-tool.sh run_tests
30 |
31 | on_failure:
32 | - 7z a failure.zip *.Rcheck\*
33 | - appveyor PushArtifact failure.zip
34 |
35 | artifacts:
36 | - path: '*.Rcheck\**\*.log'
37 | name: Logs
38 |
39 | - path: '*.Rcheck\**\*.out'
40 | name: Logs
41 |
42 | - path: '*.Rcheck\**\*.fail'
43 | name: Logs
44 |
45 | - path: '*.Rcheck\**\*.Rout'
46 | name: Logs
47 |
48 | - path: '\*_*.tar.gz'
49 | name: Bits
50 |
51 | - path: '\*_*.zip'
52 | name: Bits
53 |
--------------------------------------------------------------------------------
/inst/explore.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "explore"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{explore}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(
12 | collapse = TRUE,
13 | comment = "#>"
14 | )
15 | ```
16 |
17 | ```{r setup}
18 | library(tidyverse)
19 | library(Amelia)
20 | library(broom)
21 | library(naniar)
22 |
23 | # Use the africa dataset from Ameila
24 | data(africa)
25 |
26 | # Build some example models
27 | model_original1 <- lm(gdp_pc ~ trade + civlib, data = africa)
28 | model_original2 <- lm(gdp_pc ~ trade + civlib + infl, data = africa)
29 |
30 | set.seed(1234)
31 |
32 | imp_amelia <-
33 | amelia(
34 | x = africa,
35 | m = 5,
36 | cs = "country",
37 | ts = "year",
38 | logs = "gdp_pc",
39 | p2s = 0
40 | )
41 |
42 | shadow_africa <- as_shadow(africa)
43 |
44 | bind_row_n <- function(data, n){
45 |
46 | tibble::as_tibble(data[rep(seq_len(nrow(data)), n), ])
47 |
48 | }
49 |
50 | bind_row_n(africa, 2)
51 |
52 | # helper to bind the original shadow data `m` times
53 | # adds .m option to as_shadow
54 | africa %>%
55 | as_shadow() %>%
56 | bind_row_n(10) %>%
57 | mutate(m = rep("imp{1}"))
58 |
59 | models_imputed_df <-
60 | bind_rows(unclass(imp_amelia$imputations), .id = "m") %>%
61 | group_by(m) %>%
62 | bind_cols(shadow_africa)
63 | nest() %>%
64 | mutate(model = data %>% map( ~ lm(gdp_pc ~ trade + civlib, data = .)))
65 |
66 | models_imputed_df
67 | ```
68 |
--------------------------------------------------------------------------------
/man/glance.melded.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/glances.R
3 | \name{glance.melded}
4 | \alias{glance.melded}
5 | \title{Summarise Amelia's multiple imputations}
6 | \usage{
7 | \method{glance}{melded}(x, ...)
8 | }
9 | \arguments{
10 | \item{x}{Amelia melded imputed data}
11 |
12 | \item{...}{other arguments passed to methods}
13 | }
14 | \value{
15 | one line dataframe summary of the multiply imputed data
16 | }
17 | \description{
18 | A broom glance summary for multiple imputations from Andrew's blog post:
19 | https://www.andrewheiss.com/blog/2018/03/07/amelia-tidy-melding/
20 | Andrews note: This means properly melded parameters and the simple average
21 | of the parameters of these models are roughly the same sake of simplicty
22 | we just take the average here.
23 | }
24 |
--------------------------------------------------------------------------------
/man/mputr.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/mputr-package.R
3 | \docType{package}
4 | \name{mputr}
5 | \alias{mputr}
6 | \alias{mputr-package}
7 | \title{mputr}
8 | \description{
9 | mputr
10 | }
11 |
--------------------------------------------------------------------------------
/man/nobs.melded.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/nobs.R
3 | \name{nobs.melded}
4 | \alias{nobs.melded}
5 | \title{Take the number of observations from the first Amelia melded model}
6 | \usage{
7 | \method{nobs}{melded}(object, ...)
8 | }
9 | \arguments{
10 | \item{object}{Amelia melded model}
11 |
12 | \item{...}{other options to pass to `nobs`}
13 | }
14 | \value{
15 | integer
16 | }
17 | \description{
18 | Take the number of observations from the first Amelia melded model
19 | }
20 |
--------------------------------------------------------------------------------
/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 | \description{
10 | See \code{magrittr::\link[magrittr]{\%>\%}} for details.
11 | }
12 | \keyword{internal}
13 |
--------------------------------------------------------------------------------
/man/reexports.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/utils.R
3 | \docType{import}
4 | \name{reexports}
5 | \alias{reexports}
6 | \alias{tidy}
7 | \alias{glance}
8 | \alias{augment}
9 | \title{Objects exported from other packages}
10 | \keyword{internal}
11 | \description{
12 | These objects are imported from other packages. Follow the links
13 | below to see their documentation.
14 |
15 | \describe{
16 | \item{generics}{\code{\link[generics]{tidy}}, \code{\link[generics]{glance}}, \code{\link[generics]{augment}}}
17 | }}
18 |
19 |
--------------------------------------------------------------------------------
/man/tidy.melded.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tidiers.R
3 | \name{tidy.melded}
4 | \alias{tidy.melded}
5 | \title{Tidy summaries for melded data}
6 | \usage{
7 | \method{tidy}{melded}(x, ..., conf.int = FALSE, conf.level = 0.95)
8 | }
9 | \arguments{
10 | \item{x}{melded object from Amelia}
11 |
12 | \item{...}{other arguments passed to methods}
13 |
14 | \item{conf.int}{Return confidence intervals. Default is FALSE}
15 |
16 | \item{conf.level}{Confidence level (if confidence intervals are use).
17 | Default is 0.95.}
18 | }
19 | \value{
20 | tidy dataframe with pooled estimates from imputed data
21 | }
22 | \description{
23 | This is an approach for tidying Amelia imputed dataframes from Andrew Heiss
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/mputr.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 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 | PackageRoxygenize: rd,collate,namespace
22 |
--------------------------------------------------------------------------------