├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ └── R-CMD-check.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DESCRIPTION ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── boot_null.r ├── example_data.4.R ├── generics.r ├── helpers.R ├── helpers_old.R ├── icc_specs.r ├── plot_choices.r ├── plot_curve.r ├── plot_decisiontree.r ├── plot_samplesizes.r ├── plot_specs.r ├── plot_summary.r ├── plot_variance.r ├── reexports.R ├── run_specs.r ├── setup.R ├── setup_specs.r ├── specr-package.r ├── specr.R └── summarise_specs.r ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── cran-comments.md ├── data └── example_data.RData ├── docs ├── 404.html ├── CODE_OF_CONDUCT.html ├── CONTRIBUTING.html ├── LICENSE.html ├── articles │ ├── custom-plot.html │ ├── custom-plot_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── unnamed-chunk-10-1.png │ │ │ ├── unnamed-chunk-10-2.png │ │ │ ├── unnamed-chunk-10-3.png │ │ │ ├── unnamed-chunk-11-1.png │ │ │ ├── unnamed-chunk-3-1.png │ │ │ ├── unnamed-chunk-4-1.png │ │ │ ├── unnamed-chunk-4-2.png │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-6-1.png │ │ │ ├── unnamed-chunk-6-2.png │ │ │ ├── unnamed-chunk-7-1.png │ │ │ ├── unnamed-chunk-7-2.png │ │ │ ├── unnamed-chunk-8-1.png │ │ │ ├── unnamed-chunk-9-1.png │ │ │ ├── unnamed-chunk-9-2.png │ │ │ └── unnamed-chunk-9-3.png │ ├── decompose_var.html │ ├── decompose_var_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── unnamed-chunk-4-1.png │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-6-1.png │ │ │ └── unnamed-chunk-7-1.png │ ├── different-specifications.html │ ├── different-specifications_files │ │ └── figure-html │ │ │ ├── unnamed-chunk-10-1.png │ │ │ ├── unnamed-chunk-11-1.png │ │ │ ├── unnamed-chunk-11-2.png │ │ │ └── unnamed-chunk-5-1.png │ ├── getting-started.html │ ├── getting-started_files │ │ └── figure-html │ │ │ ├── unnamed-chunk-10-1.png │ │ │ ├── unnamed-chunk-11-1.png │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-8-1.png │ │ │ └── unnamed-chunk-9-1.png │ ├── index.html │ ├── inferences.html │ ├── inferences_files │ │ └── figure-html │ │ │ └── unnamed-chunk-9-1.png │ ├── invest-spec.html │ ├── invest-spec_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── unnamed-chunk-6-1.png │ │ │ └── unnamed-chunk-7-1.png │ ├── measurement-models.html │ ├── measurement-models_files │ │ └── figure-html │ │ │ ├── unnamed-chunk-6-1.png │ │ │ ├── unnamed-chunk-7-1.png │ │ │ └── unnamed-chunk-8-1.png │ ├── measurement_models.html │ ├── measurement_models_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-6-1.png │ │ │ ├── unnamed-chunk-7-1.png │ │ │ ├── unnamed-chunk-8-1.png │ │ │ └── unnamed-chunk-9-1.png │ ├── multilevel-models.html │ ├── multilevel-models_files │ │ └── figure-html │ │ │ └── unnamed-chunk-5-1.png │ ├── parallel-bayesian-models.html │ ├── parallel-bayesian-models_files │ │ └── figure-html │ │ │ ├── unnamed-chunk-4-1.png │ │ │ ├── unnamed-chunk-7-1.png │ │ │ └── unnamed-chunk-8-1.png │ ├── parallelization.html │ ├── progress.html │ ├── progress_files │ │ └── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ ├── random_effects.html │ ├── random_effects_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ └── figure-html │ │ │ ├── unnamed-chunk-4-1.png │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-6-1.png │ │ │ └── unnamed-chunk-7-1.png │ ├── simonsohn_inference.png │ ├── specr.html │ └── specr_files │ │ ├── accessible-code-block-0.0.1 │ │ └── empty-anchor.js │ │ └── figure-html │ │ ├── pressure-1.png │ │ ├── unnamed-chunk-10-1.png │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-5-1.png │ │ ├── unnamed-chunk-6-1.png │ │ ├── unnamed-chunk-7-1.png │ │ ├── unnamed-chunk-7-2.png │ │ ├── unnamed-chunk-8-1.png │ │ └── unnamed-chunk-9-1.png ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── index.html ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── Rplot002.png │ ├── Rplot003.png │ ├── Rplot004.png │ ├── Rplot005.png │ ├── Rplot006.png │ ├── Rplot007.png │ ├── Rplot008.png │ ├── Rplot009.png │ ├── Rplot010.png │ ├── Rplot011.png │ ├── Rplot012.png │ ├── Rplot013.png │ ├── as.data.frame.specr.object.html │ ├── as.data.frame.specr.setup.html │ ├── as_tibble.specr.object.html │ ├── as_tibble.specr.setup.html │ ├── boot_null-1.png │ ├── boot_null.html │ ├── example_data.html │ ├── figures │ │ ├── README-example-1.png │ │ ├── README-pressure-1.png │ │ ├── README-unnamed-chunk-2-1.png │ │ ├── README-unnamed-chunk-4-1.png │ │ ├── README-unnamed-chunk-5-1.png │ │ ├── README-unnamed-chunk-6-1.png │ │ └── specr_logo.png │ ├── icc_specs.html │ ├── index.html │ ├── plot.specr.boot.html │ ├── plot.specr.object-1.png │ ├── plot.specr.object-10.png │ ├── plot.specr.object-11.png │ ├── plot.specr.object-12.png │ ├── plot.specr.object-13.png │ ├── plot.specr.object-2.png │ ├── plot.specr.object-3.png │ ├── plot.specr.object-4.png │ ├── plot.specr.object-5.png │ ├── plot.specr.object-6.png │ ├── plot.specr.object-7.png │ ├── plot.specr.object-8.png │ ├── plot.specr.object-9.png │ ├── plot.specr.object.html │ ├── plot.specr.setup-1.png │ ├── plot.specr.setup-2.png │ ├── plot.specr.setup.html │ ├── plot_choices-1.png │ ├── plot_choices-2.png │ ├── plot_choices-3.png │ ├── plot_choices.html │ ├── plot_curve-1.png │ ├── plot_curve-2.png │ ├── plot_curve.html │ ├── plot_decisiontree-1.png │ ├── plot_decisiontree-2.png │ ├── plot_decisiontree-3.png │ ├── plot_decisiontree-4.png │ ├── plot_decisiontree.html │ ├── plot_samplesizes-1.png │ ├── plot_samplesizes-2.png │ ├── plot_samplesizes.html │ ├── plot_specs-1.png │ ├── plot_specs-2.png │ ├── plot_specs.html │ ├── plot_summary-1.png │ ├── plot_summary.html │ ├── plot_variance-1.png │ ├── plot_variance.html │ ├── print.specr.boot.html │ ├── print.specr.object.html │ ├── print.specr.setup.html │ ├── reexports.html │ ├── run_specs.html │ ├── setup.html │ ├── setup_specs.html │ ├── specr.html │ ├── summarise_specs.html │ ├── summary.specr.boot.html │ ├── summary.specr.object.html │ └── summary.specr.setup.html └── sitemap.xml ├── inst └── CITATION ├── man ├── as.data.frame.specr.object.Rd ├── as.data.frame.specr.setup.Rd ├── as_tibble.specr.object.Rd ├── as_tibble.specr.setup.Rd ├── boot_null.Rd ├── example_data.Rd ├── figures │ ├── README-unnamed-chunk-2-1.png │ └── specr_logo.png ├── icc_specs.Rd ├── plot.specr.boot.Rd ├── plot.specr.object.Rd ├── plot.specr.setup.Rd ├── plot_choices.Rd ├── plot_curve.Rd ├── plot_decisiontree.Rd ├── plot_samplesizes.Rd ├── plot_specs.Rd ├── plot_summary.Rd ├── plot_variance.Rd ├── print.specr.boot.Rd ├── print.specr.object.Rd ├── print.specr.setup.Rd ├── reexports.Rd ├── run_specs.Rd ├── setup.Rd ├── setup_specs.Rd ├── specr.Rd ├── summarise_specs.Rd ├── summary.specr.boot.Rd ├── summary.specr.object.Rd └── summary.specr.setup.Rd ├── specr.Rproj ├── tests ├── testthat.R └── testthat │ ├── test-generics.R │ ├── test-setup.R │ └── test-specr.R └── vignettes ├── .gitignore ├── custom-plot.rmd ├── different-specifications.Rmd ├── getting-started.rmd ├── inferences.Rmd ├── invest-spec.Rmd ├── man └── figures │ ├── README-unnamed-chunk-6-1.png │ └── README-unnamed-chunk-7-1.png ├── measurement-models.Rmd ├── multilevel-models.Rmd ├── parallel-bayesian-models.Rmd ├── parallel-bayesian-models.Rmd.orig ├── parallelization.Rmd ├── parallelization.Rmd.orig └── simonsohn_inference.png /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^specr\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | ^README\.Rmd$ 5 | ^CONTRIBUTING\.md$ 6 | ^CODE_OF_CONDUCT\.md$ 7 | ^cran-comments\.md$ 8 | ^\.github$ 9 | ^Meta$ 10 | ^docs$ 11 | ^_pkgdown\.yml$ 12 | ^\.travis\.yml$ 13 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 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@v3 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: any::rcmdcheck 45 | needs: check 46 | 47 | - uses: r-lib/actions/check-r-package@v2 48 | with: 49 | upload-snapshots: true 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .Rproj.user 3 | .Rhistory 4 | .RData 5 | .Ruserdata 6 | inst/doc 7 | doc 8 | Meta 9 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http://contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to specr 2 | 3 | This outlines how to propose a change to **specr**. 4 | 5 | ## Filing an issue 6 | 7 | The easiest way to propose a change or new feature is to file an issue. If you've found a 8 | bug, you may also create an associated issue. If possible, try to illustrate your proposal or the bug with a minimal [reproducible example](https://www.tidyverse.org/help/#reprex). 9 | 10 | ## Pull requests 11 | 12 | * Please create a Git branch for each pull request (PR). 13 | * Your contributed code should roughly follow the [R style guide](http://style.tidyverse.org). 14 | * specr uses [roxygen2](https://cran.r-project.org/package=roxygen2), with 15 | [Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/markdown.html), 16 | for documentation. 17 | * specr uses [testthat](https://cran.r-project.org/package=testthat). Adding tests to the PR makes it easier for me to merge your PR into the code base. 18 | 19 | ## Code of Conduct 20 | 21 | Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to 22 | abide by its terms. 23 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: specr 2 | Title: Conducting and Visualizing Specification Curve Analyses 3 | Version: 1.0.1 4 | Authors@R: c( 5 | person(given = "Philipp K.", 6 | family = "Masur", 7 | role = c("aut", "cre"), 8 | email = "phil.masur@gmail.com", 9 | comment = c(ORCID = "https://orcid.org/0000-0003-3065-7305")), 10 | person(given = "Michael", 11 | family = "Scharkow", 12 | role = c("aut"), 13 | email = "michael@underused.org") 14 | ) 15 | Description: Provides utilities for conducting specification curve analyses (Simonsohn, Simmons & Nelson (2020, ) or multiverse analyses (Steegen, Tuerlinckx, Gelman & Vanpaemel, 2016, ) including functions to setup, run, evaluate, and plot all specifications. 16 | License: GPL-3 17 | URL: https://masurp.github.io/specr/, https://github.com/masurp/specr 18 | BugReports: https://github.com/masurp/specr/issues 19 | Depends: 20 | R (>= 3.5.0) 21 | Imports: 22 | broom, 23 | cowplot, 24 | dplyr, 25 | furrr, 26 | future, 27 | ggplot2, 28 | ggraph, 29 | glue, 30 | igraph, 31 | lifecycle, 32 | lme4, 33 | magrittr, 34 | methods, 35 | parallelly, 36 | purrr, 37 | rlang, 38 | rsample, 39 | stringr, 40 | tibble, 41 | tidyr 42 | Suggests: 43 | broom.mixed, 44 | gapminder, 45 | ggridges, 46 | knitr, 47 | lavaan, 48 | testthat, 49 | tidyverse, 50 | performance, 51 | rmarkdown 52 | Encoding: UTF-8 53 | LazyData: true 54 | Roxygen: list(markdown = TRUE) 55 | RoxygenNote: 7.2.3 56 | VignetteBuilder: knitr 57 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(as.data.frame,specr.object) 4 | S3method(as.data.frame,specr.setup) 5 | S3method(as_tibble,specr.object) 6 | S3method(as_tibble,specr.setup) 7 | S3method(plot,specr.boot) 8 | S3method(plot,specr.object) 9 | S3method(plot,specr.setup) 10 | S3method(print,specr.boot) 11 | S3method(print,specr.object) 12 | S3method(print,specr.setup) 13 | S3method(summary,specr.boot) 14 | S3method(summary,specr.object) 15 | S3method(summary,specr.setup) 16 | export("%>%") 17 | export(as_tibble) 18 | export(boot_null) 19 | export(icc_specs) 20 | export(plot_choices) 21 | export(plot_curve) 22 | export(plot_decisiontree) 23 | export(plot_grid) 24 | export(plot_samplesizes) 25 | export(plot_specs) 26 | export(plot_summary) 27 | export(plot_variance) 28 | export(run_specs) 29 | export(setup) 30 | export(setup_specs) 31 | export(specr) 32 | export(summarise_specs) 33 | import(dplyr) 34 | import(ggplot2) 35 | importFrom(cowplot,plot_grid) 36 | importFrom(furrr,future_pmap) 37 | importFrom(future,multisession) 38 | importFrom(future,nbrOfWorkers) 39 | importFrom(future,plan) 40 | importFrom(glue,glue) 41 | importFrom(igraph,graph_from_data_frame) 42 | importFrom(lme4,VarCorr) 43 | importFrom(lme4,lmer) 44 | importFrom(magrittr,"%>%") 45 | importFrom(methods,is) 46 | importFrom(parallelly,availableCores) 47 | importFrom(purrr,cross) 48 | importFrom(purrr,map) 49 | importFrom(purrr,map2) 50 | importFrom(purrr,map_df) 51 | importFrom(purrr,pmap) 52 | importFrom(purrr,reduce) 53 | importFrom(rlang,.data) 54 | importFrom(rlang,enquo) 55 | importFrom(rlang,enquos) 56 | importFrom(rsample,analysis) 57 | importFrom(rsample,bootstraps) 58 | importFrom(stats,formula) 59 | importFrom(stats,mad) 60 | importFrom(stats,median) 61 | importFrom(stats,nobs) 62 | importFrom(stats,quantile) 63 | importFrom(stats,start) 64 | importFrom(stats,vcov) 65 | importFrom(stringr,str_glue) 66 | importFrom(stringr,str_remove_all) 67 | importFrom(tibble,as_tibble) 68 | importFrom(tibble,lst) 69 | importFrom(tibble,tibble) 70 | importFrom(tidyr,expand_grid) 71 | importFrom(tidyr,unite) 72 | importFrom(tidyr,unnest) 73 | importFrom(utils,head) 74 | importFrom(utils,packageVersion) 75 | importFrom(utils,stack) 76 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | 2 | # specr 1.0.1 3 | 4 | Development version released: 2024-05-222 5 | 6 | ## Breaking changes 7 | 8 | None 9 | 10 | ## Updates 11 | 12 | * This new development version includes new functions to conduct inferences on the specification curve analysis (the third step outlined Simohnsohn et al., 2020). 13 | 14 | - It thereby facilitates resampling under-the-null to obtain test statistics to evaluate the extremity of the specification curve analysis results. 15 | - See [this vignette](https://masurp.github.io/specr/articles/inferences.html) for a comprehensive tutorial. 16 | 17 | # specr 1.0.0 18 | 19 | CRAN release: 2023-01-20 20 | 21 | ## Breaking changes 22 | 23 | * This new version introduces a completely new analytic framework which breaks with earlier versions of specr. See [this vignette](https://masurp.github.io/specr/articles/specr.html) for a comprehensive tutorial on how to use this new framework. 24 | 25 | * A new function called `setup()` is introduced and replaces the original `setup_specs()` to make the specification of analytical choices more intuitive and comprehensive. Most importantly, it allows to set up all specifications (now also including subset analyses, additions to the formula, etc.) a priori, i.e., before the estimation of all models. 26 | 27 | - Data, analytic choices, and even parameter extraction functions can be specified before the fitting process (solving github issue #23 and #26). 28 | - Excludes some non-meaningful specifications automatically (e.g., when control and independent or dependent variable are the same). 29 | - Allows to specify all combinations of control variables or to "simplify" and only include none, each individually and all together (github issue #11). 30 | - Resulting specification can be filtered using standard `tidyverse` functions such as e.g., `filter()`. This way, one can make sure a priori that only reasonable specifications are actually included. 31 | - Produces an object of class `specr.setup`, which can be investigated using e.g., `summary()` or `plot()`. 32 | 33 | * The function `run_specs()` is replaced by `specr()`, which now only wraps around `setup()` to estimate all models. Most changes are related to increasing speed of the computations. 34 | 35 | - Most importantly, the estimation process can now be parallelized (based on `furrr`) to reduce fitting time (finally solving github issue #1). 36 | - Deals better and faster with subset analyses. 37 | - Produces an object of class `specr.object`, which can be investigated using generic function such as `summary()` and `plot()`. 38 | - Plotting function have been updated and e.g. also allow to group specification according to specific choices (github issue #19) 39 | 40 | * For more information about these major changes and how to use the new version of specr, see this [vignette](https://masurp.github.io/specr/articles/specr.html). 41 | 42 | * Please note that the functions from earlier versions are still available, but deprecated. It is hence still possible to use the older framework as implemented in version 0.2.1, but we suggest to move to the new framework of version 0.3.0 due to its increased speed and flexibility. 43 | 44 | ## Known issues/bugs 45 | 46 | * So far none... 47 | 48 | ## Acknowledgements 49 | 50 | This version of `specr` was something I wanted to tackle for a while. Although the previous versions seem to have embraced by the community and several relevant papers used them in interesting ways, certain issues kept coming up (ranging from slow fitting process to wanting to incorporate more complex analytical decisions and choices). This version is thus heavily inspired by the growing community of scholars who provide feedback and suggestions via [github](https://github.com/masurp/specr/issues). Thank you to all of you! But for this version, I want to thank two people particularly: 51 | 52 | * Big thanks go to [Matti Vuorre](https://github.com/mvuorre) who explored ways to parallelize specification curve analysis in this [blogpost](https://vuorre.netlify.app/posts/parallel-multiverse/), which became the basis for the implementation in specr. 53 | 54 | * Many thanks to [Kasper Welbers](https://github.com/kasperwelbers) who contributed some essential code within the core function. 55 | 56 | * Thanks also to [Johannes Gruber](https://github.com/JBGruber) who provided support in the final stages of building this package. 57 | 58 | 59 | # specr 0.2.2 60 | 61 | Development version released: 2020-12-04 62 | 63 | ## Breaking changes 64 | 65 | * None 66 | 67 | ## Updates 68 | 69 | * Some minor updates (related to gituhub issues) and bug fixes: 70 | 71 | - All combinations of control variables can be produced (by specifying `all.comb = TRUE`; solved github issue #21) 72 | - `run_specs()` now allows to add sets of control variabels (github issue #11) 73 | - All plotting functions allow to choose which parameter to plot 74 | - More complete results based on `broom::tidy()` and `broom::glance()` 75 | 76 | * The package further now allows to integrate: 77 | 78 | - random effects (see this [vignette](https://masurp.github.io/specr/articles/random_effects.html)) 79 | - latent measurement models (see this [vignette](https://masurp.github.io/specr/articles/measurement_models.html)) 80 | 81 | ## Known issues 82 | 83 | * Still no parallelization (github issue #1) 84 | 85 | # specr 0.2.1 86 | 87 | CRAN release: 2020-03-26 88 | 89 | ## Updates 90 | 91 | * First stable version 92 | 93 | * Tested in several environments. 94 | 95 | * Primary function is `run_specs()`, which allows to specify analytic choices and estimate all models across specifications. 96 | 97 | ## Known issues 98 | 99 | * No parallelization of the fitting process (can take very long if model fitting process is complex). 100 | 101 | * Implementation of random effect modelling and structural equation modeling potentially possible, but still unclear. 102 | 103 | * Does not allow to specify all possible combinations of control variables (github issue #21). 104 | 105 | * Does not allow to specify sets of control variables (github issue #11) 106 | 107 | 108 | -------------------------------------------------------------------------------- /R/boot_null.r: -------------------------------------------------------------------------------- 1 | #' Inference with specification curve analysis 2 | #' 3 | #' It is possible to generate the distributions for any of these test statistics 4 | #' under-the-null analytically (that is, with statistical formulas), because the 5 | #' specifications are neither statistically independent nor part of a single model. 6 | #' This function hence generates such distributions by relying on resampling under-the-null. 7 | #' This involves modifying the observed data so that the null hypothesis is known to be true, 8 | #' and then drawing random samples of the modified data. The resulting object of class 9 | #' `specr.boot` can be summarized and plotted with generic functions. 10 | #' 11 | #' @param x A fitted `specr.object`, resulting from running `specr()`. 12 | #' @param y A `specr.setup` object, resulting from running `setup()` 13 | #' @param n_samples Number of bootstrap samples to be drawn. Defaults to 500. 14 | #' @param ... Further arguments that can be passed to \code{future_map}. This only becomes 15 | #' important if parallelization is used. When a plan for parallelization is set, one 16 | #' can also set `.progress = TRUE` to print a progress bar during the fitting process. 17 | #' See details for more information on parallelization. 18 | #' 19 | #' @keywords internal 20 | #' @return a object of class `specr.boot` that represents a list with the original and bootstrapped results. 21 | #' 22 | #' @details A third step of specification curve analysis involves statistical inference, 23 | #' answering the question: considering the full set of reasonable specifications jointly, 24 | #' how inconsistent are the results with the null hypothesis of no effect? 25 | #' 26 | #' \bold{Parallelization} 27 | #' 28 | #' By default, the function fits the bootstrapped models across all specifications sequentially 29 | #' (one after the other). If the data set is large, the models complex (e.g., 30 | #' large structural equation models, negative binomial models, or Bayesian models), 31 | #' and the number of specifications is large, it can make sense to parallelize 32 | #' these operations. One simply has to load the package `furrr` (which 33 | #' in turn, builds on `future`) up front. Then parallelizing the fitting process 34 | #' works as specified in the package description of `furr`/`future` by setting a 35 | #' "plan" before running `boot_null` such as: 36 | #' 37 | #' `plan(multisession, workers = 4)` 38 | #' 39 | #' However, there are many more ways to specifically set up the plan, including 40 | #' different strategy than `multisession`. For more information, see 41 | #' `vignette("parallelization")` and the 42 | #' [reference page](https://future.futureverse.org/reference/plan.html) 43 | #' for `plan()`. 44 | #' 45 | #' @references \itemize{ 46 | #' \item Simonsohn, U., Simmons, J.P. & Nelson, L.D. (2020). Specification curve analysis. *Nature Human Behaviour, 4*, 1208–1214. https://doi.org/10.1038/s41562-020-0912-z 47 | #' } 48 | #' @export 49 | #' 50 | #' @examples 51 | #' # Setup up specifications 52 | #' 53 | #' # Requires to keep full model 54 | #' tidy_full <- function(x) { 55 | #' fit <- broom::tidy(x, conf.int = TRUE) 56 | #' fit$res <- list(x) # Store model object 57 | #' return(fit) 58 | #' } 59 | #' 60 | #' specs <- setup(data = example_data, 61 | #' y = c("y1", "y2"), 62 | #' x = c("x1", "x2"), 63 | #' model = "lm", 64 | #' controls = c("c1", "c2"), 65 | #' fun1 = tidy_full) 66 | #' 67 | #' # Run analysis 68 | #' results <- specr(specs) 69 | #' 70 | #' # Run bootstrapping 71 | #' boot_models <- boot_null(results, specs, n_samples = 2) # better 1,000! 72 | #' 73 | #' # Summarize findings 74 | #' summary(boot_models) 75 | #' 76 | #' # Plot under-the-null curves on top of specification curve 77 | #' plot(boot_models) 78 | #' 79 | boot_null <- function(x, y, n_samples = 500, ...) { 80 | 81 | start <- Sys.time() 82 | 83 | controls <- y$controls[!grepl('\\+|^1$', y$controls)] 84 | 85 | # Create samples under-the-null 86 | null_data <- x %>% 87 | as_tibble %>% 88 | tibble::rownames_to_column("number") %>% 89 | group_by(number) %>% 90 | mutate(data = list(res[[1]][["model"]])) %>% 91 | select(-res) %>% 92 | unnest(cols = c(data)) %>% 93 | mutate(obs_number = row_number()) %>% 94 | ungroup %>% 95 | tidyr::gather(dv, y_value, !!(y$y)) %>% 96 | tidyr::gather(iv, iv_value, y$x) %>% 97 | filter(!is.na(iv_value)) %>% 98 | mutate(y_null = y_value - (estimate * iv_value)) %>% 99 | select(-y_value, -estimate) %>% 100 | tidyr::spread(dv, y_null) %>% 101 | tidyr::spread(iv, iv_value) %>% 102 | select(-c(std.error, statistic, p.value, conf.low, conf.high, obs_number)) 103 | 104 | # Bootstrapping 105 | boots <- rsample::bootstraps(null_data, times = n_samples, apparent = FALSE) 106 | 107 | # function to fit sca on bootstrapped null data 108 | fit_sca <- function(split){ 109 | 110 | # prep bootstrapped sample 111 | boot_data <- rsample::analysis(split) 112 | 113 | # run sca 114 | fit <- specr( 115 | setup(data = boot_data, 116 | x = y$x, 117 | y = y$y, 118 | controls = controls, 119 | model = y$model) 120 | ) %>% 121 | as_tibble 122 | 123 | } 124 | 125 | if(methods::is(plan(), "sequential")) { 126 | 127 | # run function on each bootstrapped sample in boots 128 | boot_models = boots %>% 129 | dplyr::mutate(fit = map(splits, fit_sca, ...)) %>% 130 | select(-splits) 131 | 132 | 133 | } else { 134 | 135 | boot_models = boots %>% 136 | dplyr::mutate(fit = future_map(splits, fit_sca, ...)) %>% 137 | select(-splits) 138 | 139 | } 140 | 141 | # Compute time 142 | end <- Sys.time() 143 | time <- end-start 144 | time <- paste(round(as.numeric(time), 3), "sec elapsed") 145 | 146 | # create list 147 | boot_result <- list(observed_model = as_tibble(x) %>%select(-res), 148 | boot_models = boot_models, 149 | n_samples = nrow(boot_models), 150 | workers = nbrOfWorkers(), 151 | time = time) 152 | 153 | # Name class 154 | class(boot_result) <- "specr.boot" 155 | 156 | return(boot_result) 157 | } 158 | -------------------------------------------------------------------------------- /R/example_data.4.R: -------------------------------------------------------------------------------- 1 | #' Example data set 2 | #' 3 | #' This simulated data set can be used to explore the major function of 'specr'. 4 | #' It provides variables that can be used to mimic different independent and dependent variables, 5 | #' control variables, and grouping variables (for subset analyses). 6 | #' 7 | #' @docType data 8 | #' 9 | #' @usage data(example_data) 10 | #' 11 | #' @format A tibble 12 | #' 13 | #' @keywords datasets 14 | # 15 | #' 16 | #' @examples 17 | #' data(example_data) 18 | #' head(example_data) 19 | "example_data" 20 | -------------------------------------------------------------------------------- /R/helpers.R: -------------------------------------------------------------------------------- 1 | # Exand covariates 2 | expand_covariate <- function(covariate) { 3 | 4 | if(is.null(covariate)) { 5 | "1" 6 | } else { 7 | list( 8 | "1", 9 | do.call( 10 | "c", 11 | purrr::map( 12 | seq_along(covariate), 13 | ~combn(covariate, .x, FUN = list)) 14 | ) %>% 15 | purrr::map(~paste(.x, collapse = " + ")) 16 | ) %>% 17 | unlist 18 | } 19 | } 20 | 21 | expand_covariate_simple <- function(covariate) { 22 | 23 | if (!rlang::is_null(covariate) & length(covariate) == 1) { 24 | 25 | list(1, covariate) %>% 26 | unlist 27 | 28 | } else if (!rlang::is_null(covariate) & length(covariate) > 1) { 29 | 30 | list(1, 31 | purrr::map(1:length(covariate), ~covariate[[.x]]), 32 | covariate %>% paste(collapse = " + ")) %>% 33 | unlist 34 | 35 | } else { 36 | "1" 37 | } 38 | } 39 | 40 | # Function to determine the method of parameter extraction 41 | tidy_model <- function(f, fun1, fun2) { 42 | function(...) { 43 | fit <- do.call(f, args=list(...)) 44 | fit1 <- fun1(fit) 45 | 46 | if(is.null(fun2)) { 47 | fit1 <- fit1 %>% mutate(fit_nobs = broom::glance(fit)$nobs) 48 | return(fit1) 49 | } else { 50 | fit2 <- fun2(fit) 51 | colnames(fit2) <- paste("fit", colnames(fit2), sep = "_") 52 | fit <- bind_cols(fit1, fit2) 53 | return(fit) 54 | } 55 | } 56 | } 57 | 58 | # formats results 59 | format_results <- function(df, var, group, null = 0, desc = FALSE) { 60 | 61 | if(is.null(group)) { 62 | if (isFALSE(desc)) { 63 | df <- df %>% 64 | dplyr::arrange(!! var) 65 | } else { 66 | df <- df %>% 67 | dplyr::arrange(desc(!! var)) 68 | } 69 | } else { 70 | if (isFALSE(desc)) { 71 | df <- df %>% 72 | dplyr::arrange(!! group, !! var) 73 | } else { 74 | df <- df %>% 75 | dplyr::arrange(!! group, desc(!! var)) 76 | } 77 | } 78 | 79 | 80 | # create rank variable and color significance 81 | df <- df %>% 82 | dplyr::mutate(specifications = 1:nrow(df), 83 | color = case_when(conf.low > null ~ "#377eb8", 84 | conf.high < null ~ "#e41a1c", 85 | TRUE ~ "darkgrey")) 86 | return(df) 87 | } 88 | 89 | # get names from dots 90 | names_from_dots <- function(...) { 91 | 92 | sapply(substitute(list(...))[-1], deparse) 93 | 94 | } 95 | 96 | 97 | -------------------------------------------------------------------------------- /R/helpers_old.R: -------------------------------------------------------------------------------- 1 | 2 | # create regression formula based on setup_specs 3 | create_formula <- function(x, 4 | y, 5 | controls, 6 | ...) { 7 | 8 | if (controls == "no covariates") controls <- 1 9 | paste(y, "~", x, "+", controls) 10 | 11 | } 12 | 13 | # run specifications 14 | run_spec <- function(specs, 15 | df, 16 | conf.level, 17 | keep.results = FALSE) { 18 | results <- specs %>% 19 | dplyr::mutate(formula = pmap(specs, create_formula)) %>% 20 | tidyr::unnest(formula) %>% 21 | dplyr::mutate(res = map2(.data$model, 22 | formula, 23 | ~ do.call(.x, list(data = df, 24 | formula = .y)))) %>% 25 | dplyr::mutate(coefs = map(.data$res, 26 | broom::tidy, 27 | conf.int = TRUE, 28 | conf.level = conf.level), 29 | fit = map(.data$res, broom::glance)) %>% 30 | tidyr::unnest(.data$coefs) %>% 31 | tidyr::unnest(.data$fit, names_sep = "_") 32 | 33 | if("op" %in% names(results)) { 34 | results <- results %>% 35 | dplyr::filter(.data$term == paste(.data$y, "~", .data$x)) 36 | } else { 37 | results <- results %>% 38 | dplyr::filter(.data$term == .data$x) 39 | } 40 | 41 | results <- results %>% 42 | dplyr::select(-.data$formula, -.data$term) 43 | 44 | if (isFALSE(keep.results)) { 45 | results <- results %>% 46 | dplyr::select(-.data$res) 47 | } 48 | 49 | return(results) 50 | } 51 | 52 | # creates subsets 53 | create_subsets <- function(df, 54 | subsets) { 55 | 56 | subsets %>% 57 | stack %>% 58 | pmap(~ dplyr::filter(df, get(as.character(..2)) == ..1) %>% 59 | dplyr::mutate(filter = paste(..2, "=", ..1))) 60 | } 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /R/icc_specs.r: -------------------------------------------------------------------------------- 1 | #' Compute intraclass correlation coefficient 2 | #' 3 | #' This function extracts intraclass correlation coefficients (ICC) from a multilevel model. It can be used to decompose the variance in the outcome variable of a specification curve analysis (e.g., the regression coefficients). This approach summarises the relative importance of analytical choices by estimating the share of variance in the outcome (e.g., the regression coefficient) that different analytical choices or combinations therefor account for. To use this approach, one needs to estimate a multilevel model that includes all analytical choices as grouping variables (see examples). 4 | #' 5 | #' @param model a multilevel (i.e., mixed effects) model that captures the variances of the specification curve. 6 | #' @param percent a logical value indicating whether the ICC should also be printed as percentage. Defaults to TRUE. 7 | #' 8 | #' @return a [tibble][tibble::tibble-package] including the grouping variable, the random effect variances, the raw intraclass correlation coefficient (ICC), and the ICC in percent. 9 | #' 10 | #' @references \itemize{ 11 | #' \item Hox, J. J. (2010). Multilevel analysis: techniques and applications. New York: Routledge. 12 | #' } 13 | #' @export 14 | #' 15 | #' @examples 16 | #' # Step 1: Run spec curve analysis 17 | #' results <- run_specs(df = example_data, 18 | #' y = c("y1", "y2"), 19 | #' x = c("x1", "x2"), 20 | #' model = c("lm")) 21 | #' 22 | #' # Step 2: Estimate a multilevel model without predictors 23 | #' model <- lme4::lmer(estimate ~ 1 + (1|x) + (1|y), data = results) 24 | #' 25 | #' # Step 3: Estimate intra-class correlation 26 | #' icc_specs(model) 27 | #' 28 | #' @seealso [plot_variance()] to plot the variance decomposition. 29 | icc_specs <- function(model, 30 | percent = TRUE) { 31 | 32 | # get variance components 33 | var <- model %>% 34 | VarCorr %>% 35 | as.data.frame %>% 36 | dplyr::select(.data$grp, .data$vcov) 37 | 38 | # sum all variance components 39 | sum_var <- sum(var$vcov) 40 | 41 | # estimate icc 42 | var <- var %>% 43 | dplyr::mutate(icc = vcov/sum_var) 44 | 45 | # include percentage 46 | if (isTRUE(percent)) { 47 | var <- var %>% 48 | dplyr::mutate(percent = .data$icc*100) 49 | } 50 | 51 | return(var) 52 | } 53 | -------------------------------------------------------------------------------- /R/plot_choices.r: -------------------------------------------------------------------------------- 1 | #' Plot how analytical choices affect results 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()} function. 6 | #' and adding the argument \code{type = "choices"}. 7 | #' This functions plots how analytic choices affect the obtained results (i.e., the rank within the curve). Significant results are highlighted (negative = red, positive = blue, grey = nonsignificant). This functions creates the lower panel in \code{plot_specs()}. 8 | #' 9 | #' @param df a data frame resulting from \code{run_specs()}. 10 | #' @param var which variable should be evaluated? Defaults to estimate (the effect sizes computed by [run_specs()]). 11 | #' @param group Should the arrangement of the curve be grouped by a particular choice? 12 | #' Defaults to NULL, but can be any of the present choices (e.g., x, y, controls...) 13 | #' @param choices a vector specifying which analytical choices should be plotted. By default, all choices are plotted. 14 | #' @param desc logical value indicating whether the curve should the arranged in a descending order. Defaults to FALSE. 15 | #' @param null Indicate what value represents the 'null' hypothesis (Defaults to zero). 16 | #' 17 | #' @return a \link[ggplot2]{ggplot} object. 18 | #' @export 19 | #' 20 | #' @examples 21 | #' # Run specification curve analysis 22 | #' results <- run_specs(df = example_data, 23 | #' y = c("y1", "y2"), 24 | #' x = c("x1", "x2"), 25 | #' model = c("lm"), 26 | #' controls = c("c1", "c2"), 27 | #' subsets = list(group1 = unique(example_data$group1), 28 | #' group2 = unique(example_data$group2))) 29 | #' 30 | #' # Plot simple table of choices 31 | #' plot_choices(results) 32 | #' 33 | #' # Plot only specific choices 34 | #' plot_choices(results, 35 | #' choices = c("x", "y", "controls")) 36 | plot_choices <- function(df, 37 | var = .data$estimate, 38 | group = NULL, 39 | choices = c("x", "y", "model", "controls", "subsets"), 40 | desc = FALSE, 41 | null = 0) { 42 | 43 | # Deprecation warning 44 | lifecycle::deprecate_warn("1.0.0", "plot_choices()", "plot.specr.object()") 45 | 46 | value <- key <- NULL 47 | 48 | var <- enquo(var) 49 | group <- enquo(group) 50 | 51 | # Create basic plot 52 | df %>% 53 | format_results(var = var, group = group, null = null, desc = desc) %>% 54 | tidyr::gather(key, value, choices) %>% 55 | dplyr::mutate(key = factor(.data$key, levels = choices)) %>% 56 | ggplot(aes(x = .data$specifications, 57 | y = .data$value, 58 | color = .data$color)) + 59 | geom_point(aes(x = .data$specifications, 60 | y = .data$value), 61 | shape = 124, 62 | size = 3.35) + 63 | scale_color_identity() + 64 | theme_minimal() + 65 | facet_grid(.data$key~1, scales = "free_y", space = "free_y") + 66 | theme( 67 | axis.line = element_line("black", size = .5), 68 | legend.position = "none", 69 | panel.spacing = unit(.75, "lines"), 70 | axis.text = element_text(colour = "black"), 71 | strip.text.x = element_blank()) + 72 | labs(x = "", y = "") 73 | 74 | } 75 | -------------------------------------------------------------------------------- /R/plot_curve.r: -------------------------------------------------------------------------------- 1 | #' Plot ranked specification curve 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()} function and 6 | #' adding the argument \code{type = "curve"}. 7 | #' This function plots the a ranked specification curve. Confidence intervals can be included. Significant results are highlighted (negative = red, positive = blue, grey = nonsignificant). This functions creates the upper panel in \code{plot_specs()}. 8 | #' 9 | #' @param df a data frame resulting from \code{run_specs()}. 10 | #' @param var which variable should be evaluated? Defaults to estimate (the effect sizes computed by [run_specs()]). 11 | #' @param group Should the arrangement of the curve be grouped by a particular choice? 12 | #' Defaults to NULL, but can be any of the present choices (e.g., x, y, controls...) 13 | #' @param desc logical value indicating whether the curve should the arranged in a descending order. Defaults to FALSE. 14 | #' @param ci logical value indicating whether confidence intervals should be plotted. 15 | #' @param ribbon logical value indicating whether a ribbon instead should be plotted. 16 | #' @param legend logical value indicating whether the legend should be plotted Defaults to FALSE. 17 | #' @param null Indicate what value represents the null hypothesis (Defaults to zero) 18 | #' 19 | #' @return a \link[ggplot2]{ggplot} object. 20 | #' @export 21 | #' 22 | #' @examples 23 | #' # load additional library 24 | #' library(ggplot2) # for further customization of the plots 25 | #' 26 | #' # Run specification curve analysis 27 | #' results <- run_specs(df = example_data, 28 | #' y = c("y1", "y2"), 29 | #' x = c("x1", "x2"), 30 | #' model = c("lm"), 31 | #' controls = c("c1", "c2"), 32 | #' subsets = list(group1 = unique(example_data$group1), 33 | #' group2 = unique(example_data$group2))) 34 | #' 35 | #' # Plot simple specification curve 36 | #' plot_curve(results) 37 | #' 38 | #' # Ribbon instead of CIs and customize further 39 | #' plot_curve(results, ci = FALSE, ribbon = TRUE) + 40 | #' geom_hline(yintercept = 0) + 41 | #' geom_hline(yintercept = median(results$estimate), 42 | #' linetype = "dashed") + 43 | #' theme_linedraw() 44 | plot_curve <- function(df, 45 | var = .data$estimate, 46 | group = NULL, 47 | desc = FALSE, 48 | ci = TRUE, 49 | ribbon = FALSE, 50 | legend = FALSE, 51 | null = 0){ 52 | 53 | # Deprecation warning 54 | lifecycle::deprecate_warn("1.0.0", "plot_curve()", "plot.specr.object()") 55 | 56 | var <- enquo(var) 57 | group <- enquo(group) 58 | 59 | # Create basic plot 60 | plot <- df %>% 61 | format_results(var = var, group = group, null = null, desc = desc) %>% 62 | ggplot(aes(x = .data$specifications, 63 | y = !! var, 64 | ymin = .data$conf.low, 65 | ymax = .data$conf.high, 66 | color = .data$color)) + 67 | geom_point(aes(color = .data$color), 68 | size = 1) + 69 | theme_minimal() + 70 | scale_color_identity() + 71 | theme(strip.text = element_blank(), 72 | axis.line = element_line("black", size = .5), 73 | legend.position = "none", 74 | panel.spacing = unit(.75, "lines"), 75 | axis.text = element_text(colour = "black")) + 76 | labs(x = "") 77 | 78 | # add legends if necessary 79 | if (isFALSE(legend)) { 80 | plot <- plot + 81 | theme(legend.position = "none") 82 | } 83 | 84 | # add CIs if necessary 85 | if (isTRUE(ci)) { 86 | plot <- plot + 87 | geom_pointrange(alpha = 0.5, 88 | size = .6, 89 | fatten = 1) 90 | } 91 | 92 | # add ribbon if necessary 93 | if (isTRUE(ribbon)) { 94 | plot <- plot + 95 | geom_ribbon(aes(ymin = .data$conf.low, 96 | ymax = .data$conf.high, 97 | color = "lightgrey"), 98 | alpha = 0.25) 99 | } 100 | return(plot) 101 | } 102 | -------------------------------------------------------------------------------- /R/plot_decisiontree.r: -------------------------------------------------------------------------------- 1 | #' Plot decision tree 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()}. 6 | #' This function plots a simple decision tree that is meant to help understanding how few analytical choices may results in a large number of specifications. It is somewhat useless if the final number of specifications is very high. 7 | #' 8 | #' @param df data frame resulting from [run_specs()]. 9 | #' @param label Logical. Should labels be included? Defaults to FALSE. Produces only a reasonable plot if number of specifications is low. 10 | #' @param legend Logical. Should specific decisions be identifiable. Defaults to FALSE. 11 | #' 12 | #' @return a \link[ggplot2]{ggplot} object. 13 | #' 14 | #' @export 15 | #' 16 | #' @examples 17 | #' results <- run_specs(df = example_data, 18 | #' y = c("y1", "y2"), 19 | #' x = c("x1", "x2"), 20 | #' model = c("lm"), 21 | #' controls = c("c1", "c2")) 22 | #' 23 | #' # Basic, non-labelled decisions tree 24 | #' plot_decisiontree(results) 25 | #' 26 | #' # Labelled decisions tree 27 | #' plot_decisiontree(results, label = TRUE) 28 | #' 29 | #' # Add legend 30 | #' plot_decisiontree(results, label = TRUE, legend = TRUE) 31 | plot_decisiontree <- function(df, 32 | label = FALSE, 33 | legend = FALSE) { 34 | 35 | # Deprecation warning 36 | lifecycle::deprecate_warn("1.0.0", "plot_decisiontree()", "plot.specr.setup()") 37 | 38 | # Create data set for graph transformation 39 | df <- df %>% 40 | dplyr::select(.data$model, .data$x, .data$y, .data$controls, .data$subsets) %>% 41 | dplyr::arrange(.data$model, .data$x, .data$y, .data$controls, .data$subsets) %>% 42 | dplyr::mutate(start = "raw data") %>% 43 | dplyr::select(start, dplyr::everything()) %>% 44 | dplyr::mutate(x = paste0(.data$x, " & ", .data$model), 45 | y = paste0(.data$y, " & ", .data$x), 46 | controls = paste0(.data$controls, " & ", .data$y), 47 | subsets = paste0(.data$subsets, " & ", .data$controls)) 48 | 49 | # Create edges 50 | edges_level1 <- df %>% 51 | dplyr::select(.data$start, .data$model) %>% 52 | dplyr::rename(from = .data$start, to = .data$model) %>% 53 | unique %>% 54 | dplyr::mutate(decisions = "model") 55 | edges_level2 <- df %>% 56 | dplyr::select(.data$model, .data$x) %>% 57 | dplyr::rename(from = .data$model, to = .data$x) %>% 58 | unique %>% 59 | dplyr::mutate(decisions = "independent variable") 60 | edges_level3 <- df %>% 61 | dplyr::select(.data$x, .data$y) %>% 62 | dplyr::rename(from = .data$x, to = .data$y) %>% 63 | unique %>% 64 | dplyr::mutate(decisions = "dependent variable") 65 | edges_level4 = df %>% 66 | dplyr::select(.data$y, .data$controls) %>% 67 | dplyr::rename(from = .data$y, to = .data$controls) %>% 68 | dplyr::mutate(decisions = "control variables") 69 | edges_level5 <- df %>% 70 | dplyr::select(.data$controls, .data$subsets) %>% 71 | dplyr::rename(from = .data$controls, to = .data$subsets) %>% 72 | dplyr::mutate(decisions = "subsets") 73 | 74 | # Combine edges 75 | edge_list <- rbind(edges_level1, 76 | edges_level2, 77 | edges_level3, 78 | edges_level4, 79 | edges_level5) 80 | 81 | # Plot edges 82 | plot <- edge_list %>% 83 | graph_from_data_frame %>% 84 | ggraph::ggraph(layout = 'dendrogram', 85 | circular = FALSE) + 86 | ggraph::geom_edge_diagonal() + 87 | theme_void() 88 | 89 | # Check if legend should be plotted 90 | if(isTRUE(legend)) { 91 | plot <- plot + 92 | ggraph::geom_edge_diagonal(aes(color = .data$decisions)) + 93 | ggraph::scale_edge_color_brewer(palette = "Blues") 94 | } 95 | 96 | # Check if labels should be plotted 97 | if(isTRUE(label)) { 98 | plot <- plot + 99 | ggraph::geom_node_text(aes(label = .data$name, 100 | filter = .data$leaf), 101 | angle=90 , 102 | hjust=1, 103 | nudge_y = -0.10) + 104 | ylim(-5, NA) 105 | } 106 | 107 | return(plot) 108 | 109 | } 110 | -------------------------------------------------------------------------------- /R/plot_samplesizes.r: -------------------------------------------------------------------------------- 1 | #' Plot sample sizes 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()} 6 | #' function and adding the argument \code{type = "samplesizes"}. This function plots a histogram 7 | #' of sample sizes per specification. It can be added to the overall specification curve 8 | #' plot (see vignettes). 9 | #' 10 | #' @param df a data frame resulting from \code{run_specs()}. 11 | #' @param var which variable should be evaluated? Defaults to estimate (the effect sizes computed by [run_specs()]). 12 | #' @param group Should the arrangement of the curve be grouped by a particular choice? 13 | #' Defaults to NULL, but can be any of the present choices (e.g., x, y, controls...) 14 | #' @param desc logical value indicating whether the curve should the arranged in a descending order. Defaults to FALSE. 15 | #' 16 | #' @return a \link[ggplot2]{ggplot} object. 17 | #' 18 | #' @export 19 | #' 20 | #' @examples 21 | #' # load additional library 22 | #' library(ggplot2) # for further customization of the plots 23 | #' 24 | #' # run specification curve analysis 25 | #' results <- run_specs(df = example_data, 26 | #' y = c("y1", "y2"), 27 | #' x = c("x1", "x2"), 28 | #' model = c("lm"), 29 | #' controls = c("c1", "c2"), 30 | #' subsets = list(group1 = unique(example_data$group1), 31 | #' group2 = unique(example_data$group2))) 32 | #' # plot ranked bar chart of sample sizes 33 | #' plot_samplesizes(results) 34 | #' 35 | #' # add a horizontal line for the median sample size 36 | #' plot_samplesizes(results) + 37 | #' geom_hline(yintercept = median(results$fit_nobs), 38 | #' color = "darkgrey", 39 | #' linetype = "dashed") + 40 | #' theme_linedraw() 41 | plot_samplesizes <- function(df, 42 | var = .data$estimate, 43 | group = NULL, 44 | desc = FALSE) { 45 | 46 | # Deprecation warning 47 | lifecycle::deprecate_warn("1.0.0", "plot_samplesizes()", "plot.specr.object()") 48 | 49 | var <- enquo(var) 50 | group <- enquo(group) 51 | 52 | df %>% 53 | format_results(var = var, group = group, desc = desc) %>% 54 | ggplot(aes(x = .data$specifications, 55 | y = .data$fit_nobs)) + 56 | geom_bar(stat = "identity", 57 | fill = "grey", 58 | size = .2) + 59 | theme_minimal() + 60 | theme( 61 | axis.line = element_line("black", size = .5), 62 | legend.position = "none", 63 | panel.spacing = unit(.75, "lines"), 64 | axis.text = element_text(colour = "black")) + 65 | labs(x = "", y = "") 66 | } 67 | -------------------------------------------------------------------------------- /R/plot_specs.r: -------------------------------------------------------------------------------- 1 | #' Plot specification curve and analytical choices 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()} 6 | #' function and adding the argument \code{type = "default"}.This function plots an entire visualization of the specification curve analysis. 7 | #' The function uses the entire [tibble][tibble::tibble-package] that is produced by 8 | #' \code{run_specs()} to create a standard visualization of the specification curve analysis. 9 | #' Alternatively, one can also pass two separately created \link[ggplot2]{ggplot} objects 10 | #' to the function. In this case, it simply combines them using \code{cowplot::plot_grid}. 11 | #' Significant results are highlighted (negative = red, positive = blue, grey = nonsignificant). 12 | #' 13 | #' @param df a data frame resulting from \code{run_specs()}. 14 | #' @param plot_a a ggplot object resulting from \code{plot_curve()} (or \code{plot_choices()} respectively). 15 | #' @param plot_b a ggplot object resulting from \code{plot_choices()} (or \code{plot_curve()} respectively). 16 | #' @param choices a vector specifying which analytical choices should be plotted. By default, all choices are plotted. 17 | #' @param labels labels for the two parts of the plot 18 | #' @param rel_heights vector indicating the relative heights of the plot. 19 | #' @param desc logical value indicating whether the curve should the arranged in 20 | #' a descending order. Defaults to FALSE. 21 | #' @param ci logical value indicating whether confidence intervals should be 22 | #' plotted. 23 | #' @param ribbon logical value indicating whether a ribbon instead should be 24 | #' plotted. 25 | #' @param null Indicate what value represents the 'null' hypothesis (defaults to 26 | #' zero). 27 | #' @param ... additional arguments that can be passed to \code{plot_grid()}. 28 | #' 29 | #' @return a \link[ggplot2]{ggplot} object. 30 | #' 31 | #' @export 32 | #' 33 | #' @examples 34 | #' # load additional library 35 | #' library(ggplot2) # for further customization of the plots 36 | #' 37 | #' # run spec analysis 38 | #' results <- run_specs(example_data, 39 | #' y = c("y1", "y2"), 40 | #' x = c("x1", "x2"), 41 | #' model = "lm", 42 | #' controls = c("c1", "c2"), 43 | #' subset = list(group1 = unique(example_data$group1))) 44 | #' 45 | #' # plot results directly 46 | #' plot_specs(results) 47 | #' 48 | #' # Customize each part and then combine 49 | #' p1 <- plot_curve(results) + 50 | #' geom_hline(yintercept = 0, linetype = "dashed", color = "grey") + 51 | #' ylim(-3, 12) + 52 | #' labs(x = "", y = "regression coefficient") 53 | #' 54 | #' p2 <- plot_choices(results) + 55 | #' labs(x = "specifications (ranked)") 56 | #' 57 | #' plot_specs(plot_a = p1, # arguments must be called directly! 58 | #' plot_b = p2, 59 | #' rel_height = c(2, 2)) 60 | #'@seealso \itemize{ 61 | #' \item [plot_curve()] to plot only the specification curve. 62 | #' \item [plot_choices()] to plot only the choices panel. 63 | #' \item [plot_samplesizes()] to plot a histogram of sample sizes per specification. 64 | #'} 65 | plot_specs <- function(df = NULL, 66 | plot_a = NULL, 67 | plot_b = NULL, 68 | choices = c("x", "y", "model", "controls", "subsets"), 69 | labels = c("A", "B"), 70 | rel_heights = c(2, 3), 71 | desc = FALSE, 72 | null = 0, 73 | ci = TRUE, 74 | ribbon = FALSE, 75 | ...) { 76 | 77 | # Deprecation warning 78 | lifecycle::deprecate_warn("1.0.0", "plot_specs()", "plot.specr.object()") 79 | 80 | if (!is.null(df)) { 81 | 82 | # Create both plots 83 | plot_a <- plot_curve(df, ci = ci, ribbon = ribbon, desc = desc, null = null) 84 | plot_b <- plot_choices(df, choices = choices, desc = desc, null = null) 85 | 86 | } 87 | 88 | # Combine plots 89 | cowplot::plot_grid(plot_a, 90 | plot_b, 91 | labels = labels, 92 | align = "v", 93 | axis = "rbl", 94 | rel_heights = rel_heights, 95 | ncol = 1, 96 | ...) 97 | 98 | } 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /R/plot_summary.r: -------------------------------------------------------------------------------- 1 | #' Create box plots for given analytical choices 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()} function and adding the argument \code{type = "boxplot"}. 6 | #' This function provides a convenient way to visually investigate the effect of individual choices on the estimate of interest. It produces box-and-whisker plot(s) for each provided analytical choice. 7 | #' 8 | #' @param df a data frame resulting from \code{run_specs()}. 9 | #' @param choices a vector specifying which analytical choices should be plotted. By default, all choices are plotted. 10 | #' 11 | #' @return a \link[ggplot2]{ggplot} object. 12 | #' 13 | #' @export 14 | #' 15 | #' @examples 16 | #' # run spec analysis 17 | #' results <- run_specs(example_data, 18 | #' y = c("y1", "y2"), 19 | #' x = c("x1", "x2"), 20 | #' model = "lm", 21 | #' controls = c("c1", "c2"), 22 | #' subset = list(group1 = unique(example_data$group1))) 23 | #' 24 | #' # plot boxplot comparing specific choices 25 | #' plot_summary(results, choices = c("subsets", "controls", "y")) 26 | #' @seealso [summarise_specs()] to investigate the affect of analytical choices in more detail. 27 | plot_summary <- function(df, 28 | choices = c("x", "y", "model", "controls", "subsets")) { 29 | 30 | # Deprecation warning 31 | lifecycle::deprecate_warn("1.0.0", "plot_summary()", "plot.specr.object()") 32 | 33 | value <- key <- NULL 34 | 35 | df %>% 36 | dplyr::mutate(controls = ifelse(grepl("[+]", .data$controls), "all covariates", .data$controls)) %>% 37 | tidyr::gather(key, value, choices) %>% 38 | ggplot(aes(x = .data$value, y = .data$estimate, fill = .data$key)) + 39 | geom_boxplot(outlier.color = "red") + 40 | coord_flip() + 41 | scale_fill_brewer(palette = "Blues") + 42 | facet_grid(.data$key~1, scales = "free_y", space = "free") + 43 | theme_minimal() + 44 | theme(legend.position = "none", 45 | axis.line = element_line("black", size = .5), 46 | axis.text = element_text(colour = "black"), 47 | strip.text.x = element_blank()) + 48 | labs(x = "") 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /R/plot_variance.r: -------------------------------------------------------------------------------- 1 | #' Plot variance decomposition 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()} 6 | #' function and adding the argument \code{type = "variance"}. This functions creates a simple 7 | #' barplot that visually displays how much variance in the outcome (e.g., the regression coefficient) 8 | #' different analytical choices or combinations therefor account for. To use this approach, 9 | #' one needs to estimate a multilevel model that includes all analytical choices as 10 | #' grouping variables (see examples and vignettes). This function uses [icc_specs()] 11 | #' to compute the intraclass correlation coefficients (ICCs), which provides the data 12 | #' basis for the plot (see examples). 13 | #' 14 | #' @param model a multilevel model that captures the variances of the specification curve (based on the data frame resulting from \code{run_specs}). 15 | #' 16 | #' @return a \link[ggplot2]{ggplot} object. 17 | #' 18 | #' @export 19 | #' 20 | #' @examples 21 | #' # Step 1: Run spec curve analysis 22 | #' results <- run_specs(df = example_data, 23 | #' y = c("y1", "y2"), 24 | #' x = c("x1", "x2"), 25 | #' model = c("lm")) 26 | #' 27 | #' # Step 2: Estimate multilevel model 28 | #' library(lme4, quietly = TRUE) 29 | #' model <- lmer(estimate ~ 1 + (1|x) + (1|y), data = results) 30 | #' 31 | #' # Step 3: Plot model 32 | #' plot_variance(model) 33 | #' 34 | #' @seealso [icc_specs()] to produce a tibble that details the variance decomposition. 35 | plot_variance <- function(model) { 36 | 37 | # Deprecation warning 38 | lifecycle::deprecate_warn("1.0.0", "plot_variance()", "plot.specr.object()") 39 | 40 | 41 | icc_specs(model) %>% 42 | ggplot(aes(x = .data$grp, 43 | y = .data$percent)) + 44 | geom_bar(stat = "identity", fill = "#377eb8") + 45 | theme_minimal() + 46 | theme(axis.text = element_text(colour = "black"), 47 | axis.line.y = element_line(colour = "black"), 48 | axis.line.x = element_line(colour = "black")) + 49 | labs(x = "", y = "proportion of variance", fill = "analytical choices") 50 | } 51 | -------------------------------------------------------------------------------- /R/reexports.R: -------------------------------------------------------------------------------- 1 | #' @importFrom magrittr %>% 2 | #' @export 3 | magrittr::`%>%` 4 | 5 | #' @importFrom tibble tibble 6 | #' @export 7 | tibble::as_tibble 8 | 9 | #' @importFrom cowplot plot_grid 10 | #' @export 11 | cowplot::plot_grid 12 | 13 | -------------------------------------------------------------------------------- /R/run_specs.r: -------------------------------------------------------------------------------- 1 | #' Estimate all specifications 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function was deprecated because the new version of specr uses different analytical framework. In this framework, you should use the function [setup()] first and then run all specifications using [specr()]. 5 | #' This is the central function of the package. It runs the specification curve analysis. It takes the data frame and vectors for analytical choices related to the dependent variable, the independent variable, the type of models that should be estimated, the set of covariates that should be included (none, each individually, and all together), as well as a named list of potential subsets. The function returns a tidy tibble which includes relevant model parameters for each specification. The function \link[broom]{tidy} is used to extract relevant model parameters. Exactly what tidy considers to be a model component varies across models but is usually self-evident. 6 | #' 7 | #' @param df a data frame that includes all relevant variables 8 | #' @param y a vector denoting the dependent variables 9 | #' @param x a vector denoting independent variables 10 | #' @param model a vector denoting the model(s) that should be estimated. 11 | #' @param controls a vector denoting which control variables should be included. Defaults to NULL. 12 | #' @param subsets a named list that includes potential subsets that should be evaluated (see examples). Defaults to NULL. 13 | #' @param all.comb a logical value indicating what type of combinations of the control variables should be specified. Defaults to FALSE (i.e., none, all, and each individually). If this argument is set to TRUE, all possible combinations between the control variables are specified (see examples). 14 | #' @param conf.level the confidence level to use for the confidence interval. Must be strictly greater than 0 and less than 1. Defaults to .95, which corresponds to a 95 percent confidence interval. 15 | #' @param keep.results a logical value indicating whether the complete model object should be kept. Defaults to FALSE. 16 | #' 17 | #' @return a [tibble][tibble::tibble-package] that includes all specifications and a tidy summary of model components. 18 | #' 19 | #' @references \itemize{ 20 | #' \item Simonsohn, U., Simmons, J. P., & Nelson, L. D. (2019). Specification Curve: Descriptive and Inferential Statistics for all Plausible Specifications. Available at: https://doi.org/10.2139/ssrn.2694998 21 | #' \item Steegen, S., Tuerlinckx, F., Gelman, A., & Vanpaemel, W. (2016). Increasing Transparency Through a Multiverse Analysis. Perspectives on Psychological Science, 11(5), 702-712. https://doi.org/10.1177/1745691616658637 22 | #' } 23 | #' @export 24 | #' 25 | #' @examples 26 | #' # run specification curve analysis 27 | #' results <- run_specs(df = example_data, 28 | #' y = c("y1", "y2"), 29 | #' x = c("x1", "x2"), 30 | #' model = c("lm"), 31 | #' controls = c("c1", "c2"), 32 | #' subsets = list(group1 = unique(example_data$group1), 33 | #' group2 = unique(example_data$group2))) 34 | #' 35 | #' # Check results frame 36 | #' results 37 | #' 38 | #' @seealso [plot_specs()] to visualize the results of the specification curve analysis. 39 | run_specs <- function(df, 40 | x, 41 | y, 42 | model = "lm", 43 | controls = NULL, 44 | subsets = NULL, 45 | all.comb = FALSE, 46 | conf.level = 0.95, 47 | keep.results = FALSE) { 48 | 49 | # Deprecation warning 50 | lifecycle::deprecate_warn("1.0.0", "run_specs()", "specr()") 51 | 52 | if (rlang::is_missing(x)) { 53 | stop("You must specify at least one independent variable `x`.") 54 | } 55 | 56 | if (rlang::is_missing(y)) { 57 | stop("You must specify at least one dependent variable `y`.") 58 | } 59 | 60 | specs <- setup_specs(y = y, 61 | x = x, 62 | model = model, 63 | controls = controls, 64 | all.comb = all.comb) 65 | 66 | if (!is.null(subsets)) { 67 | 68 | if (!inherits(subsets, "list")) { 69 | wrong_class <- class(subsets) 70 | stop(glue("Subsets must be a 'list' and not a '{wrong_class}'.")) 71 | } 72 | 73 | subsets <- map(subsets, as.character) 74 | 75 | df_list <- create_subsets(df, subsets) 76 | df_list[[length(df_list)+1]] <- df %>% dplyr::mutate(filter = "all") 77 | 78 | if (length(subsets) > 1) { 79 | 80 | suppressMessages({ 81 | df_comb <- subsets %>% 82 | cross %>% 83 | map(~ create_subsets(subsets = .x, df = df) %>% 84 | map(~ dplyr::select(.x, -filter)) %>% 85 | reduce(dplyr::inner_join) %>% 86 | dplyr::mutate(filter = paste(names(.x), 87 | .x, 88 | collapse = " & ", 89 | sep = " = "))) 90 | 91 | df_all <- append(df_list, df_comb) 92 | }) 93 | 94 | } else { 95 | 96 | df_all <- df_list 97 | 98 | } 99 | 100 | if (conf.level > 1 | conf.level < 0) { 101 | stop("The confidence level must be strictly greater than 0 and less than 1.") 102 | } 103 | 104 | res <- map_df(df_all, ~ run_spec(specs, 105 | .x, 106 | conf.level = conf.level, 107 | keep.results = keep.results) %>% 108 | dplyr::mutate(subsets = unique(.x$filter))) 109 | 110 | } else { 111 | 112 | res <- run_spec(specs, 113 | df, 114 | conf.level = conf.level, 115 | keep.results = keep.results) %>% 116 | dplyr::mutate(subsets = "all") 117 | 118 | } 119 | 120 | return(res) 121 | 122 | } 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /R/setup_specs.r: -------------------------------------------------------------------------------- 1 | #' Set up specifications 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function was deprecated because the new version of specr uses a new analytic framework. In this framework, you should use the function [setup()] instead. 5 | #' This function creates a tibble that includes all possible specifications based the dependent and independent variables, model types, and control variables that are specified. This function simply produces a tibble of all combinations. It can be used to check the specified analytical choices. This function is called within [run_specs()], which estimates all specified models based on the data that are provided. 6 | #' 7 | #' @param y a vector denoting the dependent variables 8 | #' @param x a vector denoting independent variables 9 | #' @param model a vector denoting the model(s) that should be estimated. 10 | #' @param controls a vector of the control variables that should be included. Defaults to NULL. 11 | #' @param all.comb a logical value indicating what type of combinations of the control variables should be specified. Defaults to FALSE (i.e., none, all, and each individually). If this argument is set to TRUE, all possible combinations between the control variables are specified (see examples). 12 | #' 13 | #' @keywords internal 14 | #' @return a [tibble][tibble::tibble-package] that includes all possible specifications based on combinations of the analytic choices. 15 | #' @export 16 | #' 17 | #' @examples 18 | #' setup_specs(x = c("x1", "x2"), 19 | #' y = "y2", 20 | #' model = "lm", 21 | #' controls = c("c1", "c2")) 22 | #' 23 | #'@seealso [run_specs()] to run the specification curve analysis. 24 | setup_specs <- function(x, 25 | y, 26 | model, 27 | controls = NULL, 28 | all.comb = FALSE) { 29 | 30 | # Deprecation warning 31 | lifecycle::deprecate_warn("1.0.0", "setup_specs()", "setup()") 32 | 33 | if (!rlang::is_null(controls) & length(controls) == 1) { 34 | 35 | controls <- list(controls, "no covariates") %>% 36 | unlist 37 | 38 | } else if (!rlang::is_null(controls) & isFALSE(all.comb)) { 39 | 40 | controls <- list(controls %>% paste(collapse = " + "), 41 | purrr::map(1:length(controls), ~controls[[.x]]), 42 | "no covariates") %>% 43 | unlist 44 | 45 | } else if(!rlang::is_null(controls) & isTRUE(all.comb)) { 46 | 47 | controls <- list(do.call("c", lapply(seq_along(controls), 48 | function(i) utils::combn(controls, i, FUN = list))) %>% 49 | map(function(x) paste(x, collapse = " + ")), "no covariates") %>% 50 | unlist 51 | 52 | } else { 53 | 54 | controls <- "no covariates" 55 | 56 | } 57 | # Expand to all possible combinations 58 | expand.grid(x = x, 59 | y = y, 60 | model = model, 61 | controls = controls) %>% 62 | dplyr::mutate_all(as.character) %>% 63 | as_tibble 64 | } 65 | -------------------------------------------------------------------------------- /R/specr-package.r: -------------------------------------------------------------------------------- 1 | ## usethis namespace: start 2 | #' @import ggplot2 3 | #' @import dplyr 4 | #' @importFrom lme4 VarCorr lmer 5 | #' @importFrom glue glue 6 | #' @importFrom tidyr expand_grid unnest unite pivot_wider 7 | #' @importFrom rlang enquo enquos .data 8 | #' @importFrom tibble tibble as_tibble lst 9 | #' @importFrom igraph graph_from_data_frame 10 | #' @importFrom methods is 11 | #' @importFrom purrr map map2 map_df pmap reduce cross 12 | #' @importFrom furrr future_pmap 13 | #' @importFrom future nbrOfWorkers plan multisession 14 | #' @importFrom parallelly availableCores 15 | #' @importFrom stats formula mad median nobs quantile start vcov 16 | #' @importFrom stringr str_glue str_remove_all 17 | #' @importFrom utils stack head packageVersion 18 | #' @importFrom rsample bootstraps analysis 19 | ## usethis namespace: end 20 | NULL 21 | -------------------------------------------------------------------------------- /R/summarise_specs.r: -------------------------------------------------------------------------------- 1 | #' Summarise specifications 2 | #' 3 | #' @description `r lifecycle::badge("deprecated")` 4 | #' This function is deprecated because the new version of specr uses a new analytic framework. 5 | #' In this framework, you can plot a similar figure simply by using the generic \code{plot()} function. 6 | #' This function allows to inspect results of the specification curves by returning a comparatively simple summary of the results. This summary can be produced for various specific analytical choices and customized summary functions. 7 | #' 8 | #' @param df a data frame resulting from \code{run_specs()}. 9 | #' @param ... one or more grouping variables (e.g., subsets, controls,...) that denote the available analytical choices. 10 | #' @param var which variable should be evaluated? Defaults to estimate (the effect sizes computed by [run_specs()]). 11 | #' @param stats named vector or named list of summary functions (individually defined summary functions can included). If it is not named, placeholders (e.g., "fn1") will be used as column names. 12 | #' 13 | #' @return a [tibble][tibble::tibble-package]. 14 | #' 15 | #' @export 16 | #' 17 | #' @examples 18 | #' # Run specification curve analysis 19 | #' results <- run_specs(df = example_data, 20 | #' y = c("y1", "y2"), 21 | #' x = c("x1", "x2"), 22 | #' model = c("lm"), 23 | #' controls = c("c1", "c2"), 24 | #' subsets = list(group1 = unique(example_data$group1), 25 | #' group2 = unique(example_data$group2))) 26 | #' 27 | #' # overall summary 28 | #' summarise_specs(results) 29 | #' 30 | #' # Summary of specific analytical choices 31 | #' summarise_specs(results, # data frame 32 | #' x, y) # analytical choices 33 | #' 34 | #' # Summary of other parameters across several analytical choices 35 | #' summarise_specs(results, 36 | #' subsets, controls, 37 | #' var = p.value, 38 | #' stats = list(median = median, 39 | #' min = min, 40 | #' max = max)) 41 | #' 42 | #' # Unnamed vector instead of named list passed to `stats` 43 | #' summarise_specs(results, 44 | #' controls, 45 | #' stats = c(mean = mean, 46 | #' median = median)) 47 | #' 48 | #' @seealso [plot_summary()] to visually investigate the affect of analytical choices. 49 | summarise_specs <- function(df, 50 | ..., 51 | var = .data$estimate, 52 | stats = list(median = median, mad = mad, min = min, max = max, 53 | q25 = function(x) quantile(x, prob = .25), 54 | q75 = function(x) quantile(x, prob = .75))) { 55 | 56 | 57 | # Deprecation warning 58 | lifecycle::deprecate_warn("1.0.0", "summarise_specs()", "summary.specr.object()") 59 | 60 | group_var <- enquos(...) 61 | 62 | # internal function 63 | summary_specs <- function(df) { 64 | 65 | var <- enquo(var) 66 | 67 | df %>% 68 | dplyr::summarize_at(vars(!! var), stats) 69 | } 70 | 71 | # is grouping variable provided? 72 | if (length(group_var) == 0) { 73 | 74 | dplyr::bind_cols( 75 | df %>% 76 | summary_specs, 77 | df %>% 78 | dplyr::summarize(obs = median(.data$fit_nobs)) 79 | ) 80 | 81 | } else { 82 | 83 | dplyr::left_join( 84 | df %>% 85 | dplyr::group_by(!!! group_var) %>% 86 | summary_specs, 87 | df %>% 88 | dplyr::group_by(!!! group_var) %>% 89 | dplyr::summarize(obs = median(.data$fit_nobs)), 90 | by = names_from_dots(...) 91 | ) 92 | } 93 | } 94 | 95 | 96 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | destination: docs 2 | url: https://masurp.github.io/specr/index.html 3 | 4 | template: 5 | params: 6 | bootswatch: lumen 7 | 8 | reference: 9 | - title: "Conduct specification curve analysis" 10 | desc: > 11 | Core functions of the package that allow to a) setup all specifications and b) then fit models across all specifications 12 | contents: 13 | - setup 14 | - specr 15 | - boot_null 16 | - title: "Summarize results" 17 | desc: > 18 | All functions above create S3 classes that can be investigated with the generic summary function and transformed to data frames. 19 | contents: 20 | - summary.specr.setup 21 | - summary.specr.object 22 | - summary.specr.boot 23 | - title: "Visualizations" 24 | desc: > 25 | After running setup() or specr(), the resulting S3 class objects can be passed to the generic plot function to create visualizations. 26 | contents: 27 | - plot.specr.setup 28 | - plot.specr.object 29 | - plot.specr.boot 30 | - title: "Data set(s)" 31 | contents: 32 | - example_data 33 | - title: "Deprecated" 34 | desc: > 35 | The following function still exist and can be used, but are deprecated from version 1.0.0 on. 36 | contents: 37 | - setup_specs 38 | - run_specs 39 | - plot_specs 40 | - plot_curve 41 | - plot_choices 42 | - plot_summary 43 | - plot_samplesizes 44 | - plot_variance 45 | - plot_decisiontree 46 | - summarise_specs 47 | - icc_specs 48 | 49 | navbar: 50 | structure: 51 | left: [intro, reference, articles, news] 52 | right: [search, github] 53 | type: default 54 | left: 55 | - text: Getting started 56 | href: articles/getting-started.html 57 | - text: Reference 58 | href: reference/index.html 59 | - text: Articles 60 | menu: 61 | - text: Basics 62 | - text: Setting up different types of specifications 63 | href: articles/different-specifications.html 64 | - text: Visualizing specification curve analyses 65 | href: articles/custom-plot.html 66 | - text: Investigating specific specifications 67 | href: articles/invest-spec.html 68 | - text: Inferences with specification curve analysis 69 | href: articles/inferences.html 70 | - text: Parallelization 71 | href: articles/parallelization.html 72 | - text: ------- 73 | - text: Incorporating specific models 74 | - text: Structural equation models 75 | href: articles/measurement-models.html 76 | - text: Multilevel models 77 | href: articles/multilevel-models.html 78 | - text: Bayesian models 79 | href: articles/parallel-bayesian-models.html 80 | - text: News 81 | href: news/index.html 82 | right: 83 | - icon: fa-github fa-lg 84 | href: https://github.com/masurp/specr 85 | 86 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | 3 | * local OS 11.6 install, R 4.2.1 4 | * via github actions 5 | - macos-latest (release) 6 | - ubuntu-latest (devel) 7 | - ubuntu-latest (old-rel-1) 8 | - ubuntu-latest (release) 9 | - windows-latest (release) 10 | 11 | ## R CMD check results 12 | 13 | 0 errors | 0 warnings | 0 note 14 | 15 | R CMD check succeeded 16 | 17 | 18 | -------------------------------------------------------------------------------- /data/example_data.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/data/example_data.RData -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-10-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-10-2.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-10-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-10-3.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-4-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-4-2.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-6-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-6-2.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-7-2.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-9-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-9-2.png -------------------------------------------------------------------------------- /docs/articles/custom-plot_files/figure-html/unnamed-chunk-9-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/custom-plot_files/figure-html/unnamed-chunk-9-3.png -------------------------------------------------------------------------------- /docs/articles/decompose_var_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/decompose_var_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/decompose_var_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/decompose_var_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/decompose_var_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/decompose_var_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/decompose_var_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/decompose_var_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/decompose_var_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/different-specifications_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/different-specifications_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/different-specifications_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/different-specifications_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/different-specifications_files/figure-html/unnamed-chunk-11-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/different-specifications_files/figure-html/unnamed-chunk-11-2.png -------------------------------------------------------------------------------- /docs/articles/different-specifications_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/different-specifications_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/getting-started_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/getting-started_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/getting-started_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/getting-started_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/getting-started_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/getting-started_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/getting-started_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/getting-started_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/getting-started_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/getting-started_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/inferences_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/inferences_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/invest-spec_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/invest-spec_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/invest-spec_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/invest-spec_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/invest-spec_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/measurement-models_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement-models_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/measurement-models_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement-models_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/measurement-models_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement-models_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/measurement_models_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/measurement_models_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement_models_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/measurement_models_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement_models_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/measurement_models_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement_models_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/measurement_models_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement_models_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/measurement_models_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/measurement_models_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/multilevel-models_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/multilevel-models_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/parallel-bayesian-models_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/parallel-bayesian-models_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/parallel-bayesian-models_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/parallel-bayesian-models_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/parallel-bayesian-models_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/parallel-bayesian-models_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/progress_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/random_effects_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/random_effects_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/random_effects_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/random_effects_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/random_effects_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/random_effects_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/random_effects_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/random_effects_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/random_effects_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/simonsohn_inference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/simonsohn_inference.png -------------------------------------------------------------------------------- /docs/articles/specr_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/pressure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/pressure-1.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-7-2.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/specr_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/articles/specr_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

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

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $("div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 3.1.1 2 | pkgdown: 2.0.7 3 | pkgdown_sha: ~ 4 | articles: 5 | custom-plot: custom-plot.html 6 | different-specifications: different-specifications.html 7 | getting-started: getting-started.html 8 | inferences: inferences.html 9 | invest-spec: invest-spec.html 10 | measurement-models: measurement-models.html 11 | multilevel-models: multilevel-models.html 12 | parallel-bayesian-models: parallel-bayesian-models.html 13 | parallelization: parallelization.html 14 | last_built: 2024-05-22T13:15Z 15 | urls: 16 | reference: https://masurp.github.io/specr/index.html/reference 17 | article: https://masurp.github.io/specr/index.html/articles 18 | 19 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/Rplot002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot002.png -------------------------------------------------------------------------------- /docs/reference/Rplot003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot003.png -------------------------------------------------------------------------------- /docs/reference/Rplot004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot004.png -------------------------------------------------------------------------------- /docs/reference/Rplot005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot005.png -------------------------------------------------------------------------------- /docs/reference/Rplot006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot006.png -------------------------------------------------------------------------------- /docs/reference/Rplot007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot007.png -------------------------------------------------------------------------------- /docs/reference/Rplot008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot008.png -------------------------------------------------------------------------------- /docs/reference/Rplot009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot009.png -------------------------------------------------------------------------------- /docs/reference/Rplot010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot010.png -------------------------------------------------------------------------------- /docs/reference/Rplot011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot011.png -------------------------------------------------------------------------------- /docs/reference/Rplot012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot012.png -------------------------------------------------------------------------------- /docs/reference/Rplot013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/Rplot013.png -------------------------------------------------------------------------------- /docs/reference/boot_null-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/boot_null-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/figures/README-example-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-pressure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/figures/README-pressure-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/figures/README-unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/figures/README-unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/figures/README-unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/figures/README-unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/reference/figures/specr_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/figures/specr_logo.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-1.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-10.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-11.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-12.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-13.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-2.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-3.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-4.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-5.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-6.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-7.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-8.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.object-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.object-9.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.setup-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.setup-1.png -------------------------------------------------------------------------------- /docs/reference/plot.specr.setup-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot.specr.setup-2.png -------------------------------------------------------------------------------- /docs/reference/plot_choices-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_choices-1.png -------------------------------------------------------------------------------- /docs/reference/plot_choices-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_choices-2.png -------------------------------------------------------------------------------- /docs/reference/plot_choices-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_choices-3.png -------------------------------------------------------------------------------- /docs/reference/plot_curve-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_curve-1.png -------------------------------------------------------------------------------- /docs/reference/plot_curve-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_curve-2.png -------------------------------------------------------------------------------- /docs/reference/plot_decisiontree-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_decisiontree-1.png -------------------------------------------------------------------------------- /docs/reference/plot_decisiontree-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_decisiontree-2.png -------------------------------------------------------------------------------- /docs/reference/plot_decisiontree-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_decisiontree-3.png -------------------------------------------------------------------------------- /docs/reference/plot_decisiontree-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_decisiontree-4.png -------------------------------------------------------------------------------- /docs/reference/plot_samplesizes-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_samplesizes-1.png -------------------------------------------------------------------------------- /docs/reference/plot_samplesizes-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_samplesizes-2.png -------------------------------------------------------------------------------- /docs/reference/plot_specs-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_specs-1.png -------------------------------------------------------------------------------- /docs/reference/plot_specs-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_specs-2.png -------------------------------------------------------------------------------- /docs/reference/plot_summary-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_summary-1.png -------------------------------------------------------------------------------- /docs/reference/plot_variance-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/docs/reference/plot_variance-1.png -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://masurp.github.io/specr/index.html/404.html 5 | 6 | 7 | https://masurp.github.io/specr/index.html/CODE_OF_CONDUCT.html 8 | 9 | 10 | https://masurp.github.io/specr/index.html/CONTRIBUTING.html 11 | 12 | 13 | https://masurp.github.io/specr/index.html/LICENSE.html 14 | 15 | 16 | https://masurp.github.io/specr/index.html/articles/custom-plot.html 17 | 18 | 19 | https://masurp.github.io/specr/index.html/articles/decompose_var.html 20 | 21 | 22 | https://masurp.github.io/specr/index.html/articles/different-specifications.html 23 | 24 | 25 | https://masurp.github.io/specr/index.html/articles/getting-started.html 26 | 27 | 28 | https://masurp.github.io/specr/index.html/articles/index.html 29 | 30 | 31 | https://masurp.github.io/specr/index.html/articles/inferences.html 32 | 33 | 34 | https://masurp.github.io/specr/index.html/articles/invest-spec.html 35 | 36 | 37 | https://masurp.github.io/specr/index.html/articles/measurement-models.html 38 | 39 | 40 | https://masurp.github.io/specr/index.html/articles/measurement_models.html 41 | 42 | 43 | https://masurp.github.io/specr/index.html/articles/multilevel-models.html 44 | 45 | 46 | https://masurp.github.io/specr/index.html/articles/parallel-bayesian-models.html 47 | 48 | 49 | https://masurp.github.io/specr/index.html/articles/parallelization.html 50 | 51 | 52 | https://masurp.github.io/specr/index.html/articles/progress.html 53 | 54 | 55 | https://masurp.github.io/specr/index.html/articles/random_effects.html 56 | 57 | 58 | https://masurp.github.io/specr/index.html/articles/specr.html 59 | 60 | 61 | https://masurp.github.io/specr/index.html/authors.html 62 | 63 | 64 | https://masurp.github.io/specr/index.html/index.html 65 | 66 | 67 | https://masurp.github.io/specr/index.html/news/index.html 68 | 69 | 70 | https://masurp.github.io/specr/index.html/reference/as.data.frame.specr.object.html 71 | 72 | 73 | https://masurp.github.io/specr/index.html/reference/as.data.frame.specr.setup.html 74 | 75 | 76 | https://masurp.github.io/specr/index.html/reference/as_tibble.specr.object.html 77 | 78 | 79 | https://masurp.github.io/specr/index.html/reference/as_tibble.specr.setup.html 80 | 81 | 82 | https://masurp.github.io/specr/index.html/reference/boot_null.html 83 | 84 | 85 | https://masurp.github.io/specr/index.html/reference/example_data.html 86 | 87 | 88 | https://masurp.github.io/specr/index.html/reference/icc_specs.html 89 | 90 | 91 | https://masurp.github.io/specr/index.html/reference/index.html 92 | 93 | 94 | https://masurp.github.io/specr/index.html/reference/plot.specr.boot.html 95 | 96 | 97 | https://masurp.github.io/specr/index.html/reference/plot.specr.object.html 98 | 99 | 100 | https://masurp.github.io/specr/index.html/reference/plot.specr.setup.html 101 | 102 | 103 | https://masurp.github.io/specr/index.html/reference/plot_choices.html 104 | 105 | 106 | https://masurp.github.io/specr/index.html/reference/plot_curve.html 107 | 108 | 109 | https://masurp.github.io/specr/index.html/reference/plot_decisiontree.html 110 | 111 | 112 | https://masurp.github.io/specr/index.html/reference/plot_samplesizes.html 113 | 114 | 115 | https://masurp.github.io/specr/index.html/reference/plot_specs.html 116 | 117 | 118 | https://masurp.github.io/specr/index.html/reference/plot_summary.html 119 | 120 | 121 | https://masurp.github.io/specr/index.html/reference/plot_variance.html 122 | 123 | 124 | https://masurp.github.io/specr/index.html/reference/print.specr.boot.html 125 | 126 | 127 | https://masurp.github.io/specr/index.html/reference/print.specr.object.html 128 | 129 | 130 | https://masurp.github.io/specr/index.html/reference/print.specr.setup.html 131 | 132 | 133 | https://masurp.github.io/specr/index.html/reference/reexports.html 134 | 135 | 136 | https://masurp.github.io/specr/index.html/reference/run_specs.html 137 | 138 | 139 | https://masurp.github.io/specr/index.html/reference/setup.html 140 | 141 | 142 | https://masurp.github.io/specr/index.html/reference/setup_specs.html 143 | 144 | 145 | https://masurp.github.io/specr/index.html/reference/specr.html 146 | 147 | 148 | https://masurp.github.io/specr/index.html/reference/summarise_specs.html 149 | 150 | 151 | https://masurp.github.io/specr/index.html/reference/summary.specr.boot.html 152 | 153 | 154 | https://masurp.github.io/specr/index.html/reference/summary.specr.object.html 155 | 156 | 157 | https://masurp.github.io/specr/index.html/reference/summary.specr.setup.html 158 | 159 | 160 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | 2 | title <- sprintf("specr: Conducting and Visualizing Specification Curve Analyses (Version %s)", meta$Version) 3 | 4 | bibentry( 5 | bibtype = "misc", 6 | title = title, 7 | author = c(person("Philipp K.", "Masur"), person("Michael", "Scharkow")), 8 | year = "2020", 9 | url = "https://CRAN.R-project.org/package=specr", 10 | textVersion = 11 | paste("Masur, Philipp K. & Scharkow, M. (2020). specr: Conducting and Visualizing Specification Curve Analyses.", 12 | "Available from https://CRAN.R-project.org/package=specr." 13 | ), 14 | mheader = "To cite 'specr' in publications use:" 15 | ) 16 | -------------------------------------------------------------------------------- /man/as.data.frame.specr.object.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{as.data.frame.specr.object} 4 | \alias{as.data.frame.specr.object} 5 | \title{Return data.frame from specr.object} 6 | \usage{ 7 | \method{as.data.frame}{specr.object}(x, ...) 8 | } 9 | \description{ 10 | Return data.frame from specr.object 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/as.data.frame.specr.setup.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{as.data.frame.specr.setup} 4 | \alias{as.data.frame.specr.setup} 5 | \title{Return tibble from specr.setup object} 6 | \usage{ 7 | \method{as.data.frame}{specr.setup}(x, ...) 8 | } 9 | \description{ 10 | Return tibble from specr.setup object 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/as_tibble.specr.object.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{as_tibble.specr.object} 4 | \alias{as_tibble.specr.object} 5 | \title{Return tibble from specr.object} 6 | \usage{ 7 | \method{as_tibble}{specr.object}(x, ...) 8 | } 9 | \description{ 10 | Return tibble from specr.object 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/as_tibble.specr.setup.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{as_tibble.specr.setup} 4 | \alias{as_tibble.specr.setup} 5 | \title{Return tibble from specr.setup object} 6 | \usage{ 7 | \method{as_tibble}{specr.setup}(x, ...) 8 | } 9 | \description{ 10 | Return tibble from specr.setup object 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/boot_null.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/boot_null.r 3 | \name{boot_null} 4 | \alias{boot_null} 5 | \title{Inference with specification curve analysis} 6 | \usage{ 7 | boot_null(x, y, n_samples = 500, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A fitted \code{specr.object}, resulting from running \code{specr()}.} 11 | 12 | \item{y}{A \code{specr.setup} object, resulting from running \code{setup()}} 13 | 14 | \item{n_samples}{Number of bootstrap samples to be drawn. Defaults to 500.} 15 | 16 | \item{...}{Further arguments that can be passed to \code{future_map}. This only becomes 17 | important if parallelization is used. When a plan for parallelization is set, one 18 | can also set \code{.progress = TRUE} to print a progress bar during the fitting process. 19 | See details for more information on parallelization.} 20 | } 21 | \value{ 22 | a object of class \code{specr.boot} that represents a list with the original and bootstrapped results. 23 | } 24 | \description{ 25 | It is possible to generate the distributions for any of these test statistics 26 | under-the-null analytically (that is, with statistical formulas), because the 27 | specifications are neither statistically independent nor part of a single model. 28 | This function hence generates such distributions by relying on resampling under-the-null. 29 | This involves modifying the observed data so that the null hypothesis is known to be true, 30 | and then drawing random samples of the modified data. The resulting object of class 31 | \code{specr.boot} can be summarized and plotted with generic functions. 32 | } 33 | \details{ 34 | A third step of specification curve analysis involves statistical inference, 35 | answering the question: considering the full set of reasonable specifications jointly, 36 | how inconsistent are the results with the null hypothesis of no effect? 37 | 38 | \if{html}{\out{
    }}\preformatted{\\bold\{Parallelization\} 39 | }\if{html}{\out{
    }} 40 | 41 | By default, the function fits the bootstrapped models across all specifications sequentially 42 | (one after the other). If the data set is large, the models complex (e.g., 43 | large structural equation models, negative binomial models, or Bayesian models), 44 | and the number of specifications is large, it can make sense to parallelize 45 | these operations. One simply has to load the package \code{furrr} (which 46 | in turn, builds on \code{future}) up front. Then parallelizing the fitting process 47 | works as specified in the package description of \code{furr}/\code{future} by setting a 48 | "plan" before running \code{boot_null} such as: 49 | 50 | \code{plan(multisession, workers = 4)} 51 | 52 | However, there are many more ways to specifically set up the plan, including 53 | different strategy than \code{multisession}. For more information, see 54 | \code{vignette("parallelization")} and the 55 | \href{https://future.futureverse.org/reference/plan.html}{reference page} 56 | for \code{plan()}. 57 | } 58 | \examples{ 59 | # Setup up specifications 60 | 61 | # Requires to keep full model 62 | tidy_full <- function(x) { 63 | fit <- broom::tidy(x, conf.int = TRUE) 64 | fit$res <- list(x) # Store model object 65 | return(fit) 66 | } 67 | 68 | specs <- setup(data = example_data, 69 | y = c("y1", "y2"), 70 | x = c("x1", "x2"), 71 | model = "lm", 72 | controls = c("c1", "c2"), 73 | fun1 = tidy_full) 74 | 75 | # Run analysis 76 | results <- specr(specs) 77 | 78 | # Run bootstrapping 79 | boot_models <- boot_null(results, specs, n_samples = 2) # better 1,000! 80 | 81 | # Summarize findings 82 | summary(boot_models) 83 | 84 | # Plot under-the-null curves on top of specification curve 85 | plot(boot_models) 86 | 87 | } 88 | \references{ 89 | \itemize{ 90 | \item Simonsohn, U., Simmons, J.P. & Nelson, L.D. (2020). Specification curve analysis. \emph{Nature Human Behaviour, 4}, 1208–1214. https://doi.org/10.1038/s41562-020-0912-z 91 | } 92 | } 93 | \keyword{internal} 94 | -------------------------------------------------------------------------------- /man/example_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/example_data.4.R 3 | \docType{data} 4 | \name{example_data} 5 | \alias{example_data} 6 | \title{Example data set} 7 | \format{ 8 | A tibble 9 | } 10 | \usage{ 11 | data(example_data) 12 | } 13 | \description{ 14 | This simulated data set can be used to explore the major function of 'specr'. 15 | It provides variables that can be used to mimic different independent and dependent variables, 16 | control variables, and grouping variables (for subset analyses). 17 | } 18 | \examples{ 19 | data(example_data) 20 | head(example_data) 21 | } 22 | \keyword{datasets} 23 | -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/man/figures/README-unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /man/figures/specr_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/man/figures/specr_logo.png -------------------------------------------------------------------------------- /man/icc_specs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/icc_specs.r 3 | \name{icc_specs} 4 | \alias{icc_specs} 5 | \title{Compute intraclass correlation coefficient} 6 | \usage{ 7 | icc_specs(model, percent = TRUE) 8 | } 9 | \arguments{ 10 | \item{model}{a multilevel (i.e., mixed effects) model that captures the variances of the specification curve.} 11 | 12 | \item{percent}{a logical value indicating whether the ICC should also be printed as percentage. Defaults to TRUE.} 13 | } 14 | \value{ 15 | a \link[tibble:tibble-package]{tibble} including the grouping variable, the random effect variances, the raw intraclass correlation coefficient (ICC), and the ICC in percent. 16 | } 17 | \description{ 18 | This function extracts intraclass correlation coefficients (ICC) from a multilevel model. It can be used to decompose the variance in the outcome variable of a specification curve analysis (e.g., the regression coefficients). This approach summarises the relative importance of analytical choices by estimating the share of variance in the outcome (e.g., the regression coefficient) that different analytical choices or combinations therefor account for. To use this approach, one needs to estimate a multilevel model that includes all analytical choices as grouping variables (see examples). 19 | } 20 | \examples{ 21 | # Step 1: Run spec curve analysis 22 | results <- run_specs(df = example_data, 23 | y = c("y1", "y2"), 24 | x = c("x1", "x2"), 25 | model = c("lm")) 26 | 27 | # Step 2: Estimate a multilevel model without predictors 28 | model <- lme4::lmer(estimate ~ 1 + (1|x) + (1|y), data = results) 29 | 30 | # Step 3: Estimate intra-class correlation 31 | icc_specs(model) 32 | 33 | } 34 | \references{ 35 | \itemize{ 36 | \item Hox, J. J. (2010). Multilevel analysis: techniques and applications. New York: Routledge. 37 | } 38 | } 39 | \seealso{ 40 | \code{\link[=plot_variance]{plot_variance()}} to plot the variance decomposition. 41 | } 42 | -------------------------------------------------------------------------------- /man/plot.specr.boot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{plot.specr.boot} 4 | \alias{plot.specr.boot} 5 | \title{Plot specification curve and under-the-null distributions} 6 | \usage{ 7 | \method{plot}{specr.boot}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{specr.boot} object, resulting from calling \code{boot_null()}.} 11 | 12 | \item{...}{further arguments passed to or from other methods (currently ignored).} 13 | } 14 | \value{ 15 | A \link[ggplot2]{ggplot} object that can be customized further. 16 | } 17 | \description{ 18 | This function plots the original specification curve on top of 19 | 95\% quantiles of the bootstrapped 'under-the-null' distributions. 20 | } 21 | -------------------------------------------------------------------------------- /man/plot.specr.object.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{plot.specr.object} 4 | \alias{plot.specr.object} 5 | \title{Plot specification curve and analytic choices} 6 | \usage{ 7 | \method{plot}{specr.object}( 8 | x, 9 | type = "default", 10 | var = .data$estimate, 11 | group = NULL, 12 | choices = c("x", "y", "model", "controls", "subsets"), 13 | labels = c("A", "B"), 14 | rel_heights = c(2, 3), 15 | desc = FALSE, 16 | null = 0, 17 | ci = TRUE, 18 | ribbon = FALSE, 19 | formula = NULL, 20 | print = TRUE, 21 | ... 22 | ) 23 | } 24 | \arguments{ 25 | \item{x}{A \code{specr.object} object, usually resulting from calling \code{specr()}.} 26 | 27 | \item{type}{What type of figure should be plotted? If \code{type = "default"}, 28 | the standard specification curve analysis plot (the specification curve as the 29 | upper panel and an overview of the relevant choices as the lower panel) is 30 | created. If \code{type = "curve"}, only the specification curve (upper panel 31 | of the default plot) is plotted. If \code{type = "choices"}, only the choice 32 | panel (lower part of the default plot) is plotted. If \code{type = "boxplot"}, 33 | an alternative visualization of differences between choices is plotted that 34 | summarizes results per choice using box-and-whisker plot(s). If 35 | \code{type = "samplesizes"}, a barplot of sample sizes per specification is 36 | plotted. See examples for more information.} 37 | 38 | \item{var}{Which parameter should be plotted in the curve? Defaults to 39 | \code{estimate}, but other parameters (e.g., p.value, fit_r.squared,...) 40 | can be plotted too.} 41 | 42 | \item{group}{Should the arrangement of the curve be grouped by a particular choice? 43 | Defaults to NULL, but can be any of the present choices (e.g., x, y, controls...)} 44 | 45 | \item{choices}{A vector specifying which analytic choices should be plotted. 46 | By default, all choices (x, y, model, controls, subsets) are plotted.} 47 | 48 | \item{labels}{Labels for the two parts of the plot} 49 | 50 | \item{rel_heights}{vector indicating the relative heights of the plot.} 51 | 52 | \item{desc}{Logical value indicating whether the curve should the arranged in 53 | a descending order. Defaults to FALSE.} 54 | 55 | \item{null}{Indicate what value represents the 'null' hypothesis (defaults to 56 | zero).} 57 | 58 | \item{ci}{Logical value indicating whether confidence intervals should be 59 | plotted.} 60 | 61 | \item{ribbon}{Logical value indicating whether a ribbon instead should be 62 | plotted} 63 | 64 | \item{formula}{In combination with \code{type = "variance"}, you can provide 65 | a specific formula to extract specific variance components. The syntax of the 66 | formula is based on \code{lme4::lmer()} and thus looks something like, e.g.: 67 | \code{"estimate ~ 1 + (1|x) + (1|y)"} (to estimate the amount of variance 68 | explained by different independent \code{x} and dependent variables \code{y}). All other 69 | choices are then subsumed under residual variance. By no formula is provided, 70 | all choices (x, y, model, controls, and subsets) that have more than one alternative 71 | are included. See examples for further details.} 72 | 73 | \item{print}{In combination with \code{type = "variance"}, logical value indicating 74 | whether the intra-class correlations (i.e., percentages of variance explained by 75 | analstical choices) should be printed or not. Defaults to TRUE.} 76 | 77 | \item{...}{further arguments passed to or from other methods (currently ignored).} 78 | } 79 | \value{ 80 | A \link[ggplot2]{ggplot} object that can be customized further. 81 | } 82 | \description{ 83 | This function plots visualizations of the specification curve 84 | analysis. The function requires an object of class \code{specr.object}, usually 85 | the results of calling \code{specr()} to create a standard visualization of the 86 | specification curve analysis. Several types of visualizations are possible. 87 | } 88 | \examples{ 89 | \dontrun{ 90 | # Specification Curve analysis ---- 91 | # Setup specifications 92 | specs <- setup(data = example_data, 93 | y = c("y1", "y2"), 94 | x = c("x1", "x2"), 95 | model = "lm", 96 | controls = c("c1", "c2"), 97 | subsets = list(group1 = unique(example_data$group1), 98 | group2 = unique(example_data$group2))) 99 | 100 | # Run analysis 101 | results <- specr(specs) 102 | 103 | # Resulting data frame with estimates 104 | as_tibble(results) # This will be used for plotting 105 | 106 | 107 | # Visualizations --- 108 | # Plot results in various ways 109 | plot(results) # default 110 | plot(results, choices = c("x", "y")) # specific choices 111 | plot(results, ci = FALSE, ribbon = TRUE) # exclude CI and add ribbon instead 112 | plot(results, type = "curve") 113 | plot(results, type = "choices") 114 | plot(results, type = "samplesizes") 115 | plot(results, type = "boxplot") 116 | 117 | 118 | # Grouped plot 119 | plot(results, group = controls) 120 | 121 | # Alternative and specific visualizations ---- 122 | # Other variables in the resulting data set can be plotted too 123 | plot(results, 124 | type = "curve", 125 | var = fit_r.squared, # extract "r-square" instead of "estimate" 126 | ci = FALSE) 127 | 128 | # Such a plot can also be extended (e.g., by again adding the estimates with 129 | # confidence intervals) 130 | library(ggplot2) 131 | plot(results, type = "curve", var = fit_r.squared) + 132 | geom_point(aes(y = estimate), shape = 5) + 133 | labs(x = "specifications", y = "r-squared | estimate") 134 | 135 | # We can also investigate how much variance is explained by each analytical choice 136 | plot(results, type = "variance") 137 | 138 | # By providing a specific formula in `lme4::lmer()`-style, we can extract specific choices 139 | # and also include interactions between chocies 140 | plot(results, 141 | type = "variance", 142 | formula = "estimate ~ 1 + (1|x) + (1|y) + (1|group1) + (1|x:y)") 143 | 144 | ## Combining several plots ---- 145 | # `specr` also exports the function `plot_grid()` from the package `cowplot`, which 146 | # can be used to combine plots meaningfully 147 | a <- plot(results, "curve") 148 | b <- plot(results, "choices", choices = c("x", "y", "controls")) 149 | c <- plot(results, "samplesizes") 150 | plot_grid(a, b, c, 151 | align = "v", 152 | axis = "rbl", 153 | rel_heights = c(2, 3, 1), 154 | ncol = 1) 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /man/plot.specr.setup.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{plot.specr.setup} 4 | \alias{plot.specr.setup} 5 | \title{Plot visualization of the specification setup} 6 | \usage{ 7 | \method{plot}{specr.setup}(x, layout = "dendrogram", circular = FALSE, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{specr.setup} object, usually resulting from calling \code{setup()}.} 11 | 12 | \item{layout}{The type of layout to create for the garden of forking path. Defaults to "dendrogram". See \code{?ggraph} for options.} 13 | 14 | \item{circular}{Should the layout be transformed into a radial representation. Only possible for some layouts. Defaults to FALSE.} 15 | 16 | \item{...}{further arguments passed to or from other methods (currently ignored).} 17 | } 18 | \value{ 19 | A \link[ggplot2]{ggplot} object that can be customized further. 20 | } 21 | \description{ 22 | This function plots a visual summary of the specification setup. 23 | It requires an object of class \code{specr.setup}, usually 24 | the result of calling \code{setup()}. 25 | } 26 | \examples{ 27 | \dontrun{ 28 | specs <- setup(data = example_data, 29 | x = c("x1", "x2", "x3"), 30 | y = c("y1", "y2"), 31 | model = c("lm", "glm"), 32 | controls = "c1", 33 | subsets = list(group2 = unique(example_data$group2))) 34 | 35 | plot(specs) 36 | plot(specs, circular = TRUE) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /man/plot_choices.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_choices.r 3 | \name{plot_choices} 4 | \alias{plot_choices} 5 | \title{Plot how analytical choices affect results} 6 | \usage{ 7 | plot_choices( 8 | df, 9 | var = .data$estimate, 10 | group = NULL, 11 | choices = c("x", "y", "model", "controls", "subsets"), 12 | desc = FALSE, 13 | null = 0 14 | ) 15 | } 16 | \arguments{ 17 | \item{df}{a data frame resulting from \code{run_specs()}.} 18 | 19 | \item{var}{which variable should be evaluated? Defaults to estimate (the effect sizes computed by \code{\link[=run_specs]{run_specs()}}).} 20 | 21 | \item{group}{Should the arrangement of the curve be grouped by a particular choice? 22 | Defaults to NULL, but can be any of the present choices (e.g., x, y, controls...)} 23 | 24 | \item{choices}{a vector specifying which analytical choices should be plotted. By default, all choices are plotted.} 25 | 26 | \item{desc}{logical value indicating whether the curve should the arranged in a descending order. Defaults to FALSE.} 27 | 28 | \item{null}{Indicate what value represents the 'null' hypothesis (Defaults to zero).} 29 | } 30 | \value{ 31 | a \link[ggplot2]{ggplot} object. 32 | } 33 | \description{ 34 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 35 | This function is deprecated because the new version of specr uses a new analytic framework. 36 | In this framework, you can plot a similar figure simply by using the generic \code{plot()} function. 37 | and adding the argument \code{type = "choices"}. 38 | This functions plots how analytic choices affect the obtained results (i.e., the rank within the curve). Significant results are highlighted (negative = red, positive = blue, grey = nonsignificant). This functions creates the lower panel in \code{plot_specs()}. 39 | } 40 | \examples{ 41 | # Run specification curve analysis 42 | results <- run_specs(df = example_data, 43 | y = c("y1", "y2"), 44 | x = c("x1", "x2"), 45 | model = c("lm"), 46 | controls = c("c1", "c2"), 47 | subsets = list(group1 = unique(example_data$group1), 48 | group2 = unique(example_data$group2))) 49 | 50 | # Plot simple table of choices 51 | plot_choices(results) 52 | 53 | # Plot only specific choices 54 | plot_choices(results, 55 | choices = c("x", "y", "controls")) 56 | } 57 | -------------------------------------------------------------------------------- /man/plot_curve.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_curve.r 3 | \name{plot_curve} 4 | \alias{plot_curve} 5 | \title{Plot ranked specification curve} 6 | \usage{ 7 | plot_curve( 8 | df, 9 | var = .data$estimate, 10 | group = NULL, 11 | desc = FALSE, 12 | ci = TRUE, 13 | ribbon = FALSE, 14 | legend = FALSE, 15 | null = 0 16 | ) 17 | } 18 | \arguments{ 19 | \item{df}{a data frame resulting from \code{run_specs()}.} 20 | 21 | \item{var}{which variable should be evaluated? Defaults to estimate (the effect sizes computed by \code{\link[=run_specs]{run_specs()}}).} 22 | 23 | \item{group}{Should the arrangement of the curve be grouped by a particular choice? 24 | Defaults to NULL, but can be any of the present choices (e.g., x, y, controls...)} 25 | 26 | \item{desc}{logical value indicating whether the curve should the arranged in a descending order. Defaults to FALSE.} 27 | 28 | \item{ci}{logical value indicating whether confidence intervals should be plotted.} 29 | 30 | \item{ribbon}{logical value indicating whether a ribbon instead should be plotted.} 31 | 32 | \item{legend}{logical value indicating whether the legend should be plotted Defaults to FALSE.} 33 | 34 | \item{null}{Indicate what value represents the null hypothesis (Defaults to zero)} 35 | } 36 | \value{ 37 | a \link[ggplot2]{ggplot} object. 38 | } 39 | \description{ 40 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 41 | This function is deprecated because the new version of specr uses a new analytic framework. 42 | In this framework, you can plot a similar figure simply by using the generic \code{plot()} function and 43 | adding the argument \code{type = "curve"}. 44 | This function plots the a ranked specification curve. Confidence intervals can be included. Significant results are highlighted (negative = red, positive = blue, grey = nonsignificant). This functions creates the upper panel in \code{plot_specs()}. 45 | } 46 | \examples{ 47 | # load additional library 48 | library(ggplot2) # for further customization of the plots 49 | 50 | # Run specification curve analysis 51 | results <- run_specs(df = example_data, 52 | y = c("y1", "y2"), 53 | x = c("x1", "x2"), 54 | model = c("lm"), 55 | controls = c("c1", "c2"), 56 | subsets = list(group1 = unique(example_data$group1), 57 | group2 = unique(example_data$group2))) 58 | 59 | # Plot simple specification curve 60 | plot_curve(results) 61 | 62 | # Ribbon instead of CIs and customize further 63 | plot_curve(results, ci = FALSE, ribbon = TRUE) + 64 | geom_hline(yintercept = 0) + 65 | geom_hline(yintercept = median(results$estimate), 66 | linetype = "dashed") + 67 | theme_linedraw() 68 | } 69 | -------------------------------------------------------------------------------- /man/plot_decisiontree.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_decisiontree.r 3 | \name{plot_decisiontree} 4 | \alias{plot_decisiontree} 5 | \title{Plot decision tree} 6 | \usage{ 7 | plot_decisiontree(df, label = FALSE, legend = FALSE) 8 | } 9 | \arguments{ 10 | \item{df}{data frame resulting from \code{\link[=run_specs]{run_specs()}}.} 11 | 12 | \item{label}{Logical. Should labels be included? Defaults to FALSE. Produces only a reasonable plot if number of specifications is low.} 13 | 14 | \item{legend}{Logical. Should specific decisions be identifiable. Defaults to FALSE.} 15 | } 16 | \value{ 17 | a \link[ggplot2]{ggplot} object. 18 | } 19 | \description{ 20 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 21 | This function is deprecated because the new version of specr uses a new analytic framework. 22 | In this framework, you can plot a similar figure simply by using the generic \code{plot()}. 23 | This function plots a simple decision tree that is meant to help understanding how few analytical choices may results in a large number of specifications. It is somewhat useless if the final number of specifications is very high. 24 | } 25 | \examples{ 26 | results <- run_specs(df = example_data, 27 | y = c("y1", "y2"), 28 | x = c("x1", "x2"), 29 | model = c("lm"), 30 | controls = c("c1", "c2")) 31 | 32 | # Basic, non-labelled decisions tree 33 | plot_decisiontree(results) 34 | 35 | # Labelled decisions tree 36 | plot_decisiontree(results, label = TRUE) 37 | 38 | # Add legend 39 | plot_decisiontree(results, label = TRUE, legend = TRUE) 40 | } 41 | -------------------------------------------------------------------------------- /man/plot_samplesizes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_samplesizes.r 3 | \name{plot_samplesizes} 4 | \alias{plot_samplesizes} 5 | \title{Plot sample sizes} 6 | \usage{ 7 | plot_samplesizes(df, var = .data$estimate, group = NULL, desc = FALSE) 8 | } 9 | \arguments{ 10 | \item{df}{a data frame resulting from \code{run_specs()}.} 11 | 12 | \item{var}{which variable should be evaluated? Defaults to estimate (the effect sizes computed by \code{\link[=run_specs]{run_specs()}}).} 13 | 14 | \item{group}{Should the arrangement of the curve be grouped by a particular choice? 15 | Defaults to NULL, but can be any of the present choices (e.g., x, y, controls...)} 16 | 17 | \item{desc}{logical value indicating whether the curve should the arranged in a descending order. Defaults to FALSE.} 18 | } 19 | \value{ 20 | a \link[ggplot2]{ggplot} object. 21 | } 22 | \description{ 23 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 24 | This function is deprecated because the new version of specr uses a new analytic framework. 25 | In this framework, you can plot a similar figure simply by using the generic \code{plot()} 26 | function and adding the argument \code{type = "samplesizes"}. This function plots a histogram 27 | of sample sizes per specification. It can be added to the overall specification curve 28 | plot (see vignettes). 29 | } 30 | \examples{ 31 | # load additional library 32 | library(ggplot2) # for further customization of the plots 33 | 34 | # run specification curve analysis 35 | results <- run_specs(df = example_data, 36 | y = c("y1", "y2"), 37 | x = c("x1", "x2"), 38 | model = c("lm"), 39 | controls = c("c1", "c2"), 40 | subsets = list(group1 = unique(example_data$group1), 41 | group2 = unique(example_data$group2))) 42 | # plot ranked bar chart of sample sizes 43 | plot_samplesizes(results) 44 | 45 | # add a horizontal line for the median sample size 46 | plot_samplesizes(results) + 47 | geom_hline(yintercept = median(results$fit_nobs), 48 | color = "darkgrey", 49 | linetype = "dashed") + 50 | theme_linedraw() 51 | } 52 | -------------------------------------------------------------------------------- /man/plot_specs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_specs.r 3 | \name{plot_specs} 4 | \alias{plot_specs} 5 | \title{Plot specification curve and analytical choices} 6 | \usage{ 7 | plot_specs( 8 | df = NULL, 9 | plot_a = NULL, 10 | plot_b = NULL, 11 | choices = c("x", "y", "model", "controls", "subsets"), 12 | labels = c("A", "B"), 13 | rel_heights = c(2, 3), 14 | desc = FALSE, 15 | null = 0, 16 | ci = TRUE, 17 | ribbon = FALSE, 18 | ... 19 | ) 20 | } 21 | \arguments{ 22 | \item{df}{a data frame resulting from \code{run_specs()}.} 23 | 24 | \item{plot_a}{a ggplot object resulting from \code{plot_curve()} (or \code{plot_choices()} respectively).} 25 | 26 | \item{plot_b}{a ggplot object resulting from \code{plot_choices()} (or \code{plot_curve()} respectively).} 27 | 28 | \item{choices}{a vector specifying which analytical choices should be plotted. By default, all choices are plotted.} 29 | 30 | \item{labels}{labels for the two parts of the plot} 31 | 32 | \item{rel_heights}{vector indicating the relative heights of the plot.} 33 | 34 | \item{desc}{logical value indicating whether the curve should the arranged in 35 | a descending order. Defaults to FALSE.} 36 | 37 | \item{null}{Indicate what value represents the 'null' hypothesis (defaults to 38 | zero).} 39 | 40 | \item{ci}{logical value indicating whether confidence intervals should be 41 | plotted.} 42 | 43 | \item{ribbon}{logical value indicating whether a ribbon instead should be 44 | plotted.} 45 | 46 | \item{...}{additional arguments that can be passed to \code{plot_grid()}.} 47 | } 48 | \value{ 49 | a \link[ggplot2]{ggplot} object. 50 | } 51 | \description{ 52 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 53 | This function is deprecated because the new version of specr uses a new analytic framework. 54 | In this framework, you can plot a similar figure simply by using the generic \code{plot()} 55 | function and adding the argument \code{type = "default"}.This function plots an entire visualization of the specification curve analysis. 56 | The function uses the entire \link[tibble:tibble-package]{tibble} that is produced by 57 | \code{run_specs()} to create a standard visualization of the specification curve analysis. 58 | Alternatively, one can also pass two separately created \link[ggplot2]{ggplot} objects 59 | to the function. In this case, it simply combines them using \code{cowplot::plot_grid}. 60 | Significant results are highlighted (negative = red, positive = blue, grey = nonsignificant). 61 | } 62 | \examples{ 63 | # load additional library 64 | library(ggplot2) # for further customization of the plots 65 | 66 | # run spec analysis 67 | results <- run_specs(example_data, 68 | y = c("y1", "y2"), 69 | x = c("x1", "x2"), 70 | model = "lm", 71 | controls = c("c1", "c2"), 72 | subset = list(group1 = unique(example_data$group1))) 73 | 74 | # plot results directly 75 | plot_specs(results) 76 | 77 | # Customize each part and then combine 78 | p1 <- plot_curve(results) + 79 | geom_hline(yintercept = 0, linetype = "dashed", color = "grey") + 80 | ylim(-3, 12) + 81 | labs(x = "", y = "regression coefficient") 82 | 83 | p2 <- plot_choices(results) + 84 | labs(x = "specifications (ranked)") 85 | 86 | plot_specs(plot_a = p1, # arguments must be called directly! 87 | plot_b = p2, 88 | rel_height = c(2, 2)) 89 | } 90 | \seealso{ 91 | \itemize{ 92 | \item \code{\link[=plot_curve]{plot_curve()}} to plot only the specification curve. 93 | \item \code{\link[=plot_choices]{plot_choices()}} to plot only the choices panel. 94 | \item \code{\link[=plot_samplesizes]{plot_samplesizes()}} to plot a histogram of sample sizes per specification. 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /man/plot_summary.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_summary.r 3 | \name{plot_summary} 4 | \alias{plot_summary} 5 | \title{Create box plots for given analytical choices} 6 | \usage{ 7 | plot_summary(df, choices = c("x", "y", "model", "controls", "subsets")) 8 | } 9 | \arguments{ 10 | \item{df}{a data frame resulting from \code{run_specs()}.} 11 | 12 | \item{choices}{a vector specifying which analytical choices should be plotted. By default, all choices are plotted.} 13 | } 14 | \value{ 15 | a \link[ggplot2]{ggplot} object. 16 | } 17 | \description{ 18 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 19 | This function is deprecated because the new version of specr uses a new analytic framework. 20 | In this framework, you can plot a similar figure simply by using the generic \code{plot()} function and adding the argument \code{type = "boxplot"}. 21 | This function provides a convenient way to visually investigate the effect of individual choices on the estimate of interest. It produces box-and-whisker plot(s) for each provided analytical choice. 22 | } 23 | \examples{ 24 | # run spec analysis 25 | results <- run_specs(example_data, 26 | y = c("y1", "y2"), 27 | x = c("x1", "x2"), 28 | model = "lm", 29 | controls = c("c1", "c2"), 30 | subset = list(group1 = unique(example_data$group1))) 31 | 32 | # plot boxplot comparing specific choices 33 | plot_summary(results, choices = c("subsets", "controls", "y")) 34 | } 35 | \seealso{ 36 | \code{\link[=summarise_specs]{summarise_specs()}} to investigate the affect of analytical choices in more detail. 37 | } 38 | -------------------------------------------------------------------------------- /man/plot_variance.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_variance.r 3 | \name{plot_variance} 4 | \alias{plot_variance} 5 | \title{Plot variance decomposition} 6 | \usage{ 7 | plot_variance(model) 8 | } 9 | \arguments{ 10 | \item{model}{a multilevel model that captures the variances of the specification curve (based on the data frame resulting from \code{run_specs}).} 11 | } 12 | \value{ 13 | a \link[ggplot2]{ggplot} object. 14 | } 15 | \description{ 16 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 17 | This function is deprecated because the new version of specr uses a new analytic framework. 18 | In this framework, you can plot a similar figure simply by using the generic \code{plot()} 19 | function and adding the argument \code{type = "variance"}. This functions creates a simple 20 | barplot that visually displays how much variance in the outcome (e.g., the regression coefficient) 21 | different analytical choices or combinations therefor account for. To use this approach, 22 | one needs to estimate a multilevel model that includes all analytical choices as 23 | grouping variables (see examples and vignettes). This function uses \code{\link[=icc_specs]{icc_specs()}} 24 | to compute the intraclass correlation coefficients (ICCs), which provides the data 25 | basis for the plot (see examples). 26 | } 27 | \examples{ 28 | # Step 1: Run spec curve analysis 29 | results <- run_specs(df = example_data, 30 | y = c("y1", "y2"), 31 | x = c("x1", "x2"), 32 | model = c("lm")) 33 | 34 | # Step 2: Estimate multilevel model 35 | library(lme4, quietly = TRUE) 36 | model <- lmer(estimate ~ 1 + (1|x) + (1|y), data = results) 37 | 38 | # Step 3: Plot model 39 | plot_variance(model) 40 | 41 | } 42 | \seealso{ 43 | \code{\link[=icc_specs]{icc_specs()}} to produce a tibble that details the variance decomposition. 44 | } 45 | -------------------------------------------------------------------------------- /man/print.specr.boot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{print.specr.boot} 4 | \alias{print.specr.boot} 5 | \title{Print method for S3 class "specr.book"} 6 | \usage{ 7 | \method{print}{specr.boot}(x, ...) 8 | } 9 | \description{ 10 | Print method for S3 class "specr.book" 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/print.specr.object.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{print.specr.object} 4 | \alias{print.specr.object} 5 | \title{Print method for S3 class "specr.object"} 6 | \usage{ 7 | \method{print}{specr.object}(x, ...) 8 | } 9 | \description{ 10 | Print method for S3 class "specr.object" 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/print.specr.setup.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{print.specr.setup} 4 | \alias{print.specr.setup} 5 | \title{Print method for S3 class "specr.setup"} 6 | \usage{ 7 | \method{print}{specr.setup}(x, ...) 8 | } 9 | \description{ 10 | Print method for S3 class "specr.setup" 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reexports.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{\%>\%} 7 | \alias{as_tibble} 8 | \alias{plot_grid} 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{cowplot}{\code{\link[cowplot]{plot_grid}}} 17 | 18 | \item{magrittr}{\code{\link[magrittr:pipe]{\%>\%}}} 19 | 20 | \item{tibble}{\code{\link[tibble]{as_tibble}}} 21 | }} 22 | 23 | -------------------------------------------------------------------------------- /man/run_specs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/run_specs.r 3 | \name{run_specs} 4 | \alias{run_specs} 5 | \title{Estimate all specifications} 6 | \usage{ 7 | run_specs( 8 | df, 9 | x, 10 | y, 11 | model = "lm", 12 | controls = NULL, 13 | subsets = NULL, 14 | all.comb = FALSE, 15 | conf.level = 0.95, 16 | keep.results = FALSE 17 | ) 18 | } 19 | \arguments{ 20 | \item{df}{a data frame that includes all relevant variables} 21 | 22 | \item{x}{a vector denoting independent variables} 23 | 24 | \item{y}{a vector denoting the dependent variables} 25 | 26 | \item{model}{a vector denoting the model(s) that should be estimated.} 27 | 28 | \item{controls}{a vector denoting which control variables should be included. Defaults to NULL.} 29 | 30 | \item{subsets}{a named list that includes potential subsets that should be evaluated (see examples). Defaults to NULL.} 31 | 32 | \item{all.comb}{a logical value indicating what type of combinations of the control variables should be specified. Defaults to FALSE (i.e., none, all, and each individually). If this argument is set to TRUE, all possible combinations between the control variables are specified (see examples).} 33 | 34 | \item{conf.level}{the confidence level to use for the confidence interval. Must be strictly greater than 0 and less than 1. Defaults to .95, which corresponds to a 95 percent confidence interval.} 35 | 36 | \item{keep.results}{a logical value indicating whether the complete model object should be kept. Defaults to FALSE.} 37 | } 38 | \value{ 39 | a \link[tibble:tibble-package]{tibble} that includes all specifications and a tidy summary of model components. 40 | } 41 | \description{ 42 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 43 | This function was deprecated because the new version of specr uses different analytical framework. In this framework, you should use the function \code{\link[=setup]{setup()}} first and then run all specifications using \code{\link[=specr]{specr()}}. 44 | This is the central function of the package. It runs the specification curve analysis. It takes the data frame and vectors for analytical choices related to the dependent variable, the independent variable, the type of models that should be estimated, the set of covariates that should be included (none, each individually, and all together), as well as a named list of potential subsets. The function returns a tidy tibble which includes relevant model parameters for each specification. The function \link[broom]{tidy} is used to extract relevant model parameters. Exactly what tidy considers to be a model component varies across models but is usually self-evident. 45 | } 46 | \examples{ 47 | # run specification curve analysis 48 | results <- run_specs(df = example_data, 49 | y = c("y1", "y2"), 50 | x = c("x1", "x2"), 51 | model = c("lm"), 52 | controls = c("c1", "c2"), 53 | subsets = list(group1 = unique(example_data$group1), 54 | group2 = unique(example_data$group2))) 55 | 56 | # Check results frame 57 | results 58 | 59 | } 60 | \references{ 61 | \itemize{ 62 | \item Simonsohn, U., Simmons, J. P., & Nelson, L. D. (2019). Specification Curve: Descriptive and Inferential Statistics for all Plausible Specifications. Available at: https://doi.org/10.2139/ssrn.2694998 63 | \item Steegen, S., Tuerlinckx, F., Gelman, A., & Vanpaemel, W. (2016). Increasing Transparency Through a Multiverse Analysis. Perspectives on Psychological Science, 11(5), 702-712. https://doi.org/10.1177/1745691616658637 64 | } 65 | } 66 | \seealso{ 67 | \code{\link[=plot_specs]{plot_specs()}} to visualize the results of the specification curve analysis. 68 | } 69 | -------------------------------------------------------------------------------- /man/setup_specs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/setup_specs.r 3 | \name{setup_specs} 4 | \alias{setup_specs} 5 | \title{Set up specifications} 6 | \usage{ 7 | setup_specs(x, y, model, controls = NULL, all.comb = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{a vector denoting independent variables} 11 | 12 | \item{y}{a vector denoting the dependent variables} 13 | 14 | \item{model}{a vector denoting the model(s) that should be estimated.} 15 | 16 | \item{controls}{a vector of the control variables that should be included. Defaults to NULL.} 17 | 18 | \item{all.comb}{a logical value indicating what type of combinations of the control variables should be specified. Defaults to FALSE (i.e., none, all, and each individually). If this argument is set to TRUE, all possible combinations between the control variables are specified (see examples).} 19 | } 20 | \value{ 21 | a \link[tibble:tibble-package]{tibble} that includes all possible specifications based on combinations of the analytic choices. 22 | } 23 | \description{ 24 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 25 | This function was deprecated because the new version of specr uses a new analytic framework. In this framework, you should use the function \code{\link[=setup]{setup()}} instead. 26 | This function creates a tibble that includes all possible specifications based the dependent and independent variables, model types, and control variables that are specified. This function simply produces a tibble of all combinations. It can be used to check the specified analytical choices. This function is called within \code{\link[=run_specs]{run_specs()}}, which estimates all specified models based on the data that are provided. 27 | } 28 | \examples{ 29 | setup_specs(x = c("x1", "x2"), 30 | y = "y2", 31 | model = "lm", 32 | controls = c("c1", "c2")) 33 | 34 | } 35 | \seealso{ 36 | \code{\link[=run_specs]{run_specs()}} to run the specification curve analysis. 37 | } 38 | \keyword{internal} 39 | -------------------------------------------------------------------------------- /man/specr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/specr.R 3 | \name{specr} 4 | \alias{specr} 5 | \title{Fit models across all specifications} 6 | \usage{ 7 | specr(x, data = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{specr.setup} object resulting from \code{setup} or a tibble that 11 | contains the relevant specifications (e.g., a tibble resulting from 12 | \code{as_tibble(setup(...))}).} 13 | 14 | \item{data}{If x is not an object of "specr.setup" and simply a tibble, you 15 | need to provide the data set that should be used. Defaults to NULL as it is 16 | assumend that most users will create an object of class "specr.setup" that they'll 17 | pass to \code{specr()}.} 18 | 19 | \item{...}{Further arguments that can be passed to \code{future_pmap}. This only becomes 20 | important if parallelization is used. For example, if a custom model function is used 21 | this involves passing \code{furrr_options} passing to the argument \code{.options}. 22 | When a plan for parallelization is set, one can also set \code{.progress = TRUE} 23 | to print a progress bar during the fitting process. See details for more information 24 | on parallelization.} 25 | } 26 | \value{ 27 | An object of class \code{specr.object}, which includes a data frame 28 | with all specifications their respective results along with many other useful 29 | information about the model. Parameters are extracted via the function passed 30 | to \code{setup}. By default this is \code{broom::tidy()} and the function 31 | \code{broom::glance()}).Several other aspects and information are included in 32 | the resulting class (e.g., number of specifications, time elapsed, subsets 33 | included in the analyses). Use \code{methods(class = "specr.object")} for 34 | an overview on available methods. 35 | } 36 | \description{ 37 | Runs the specification/multiverse analysis across specified models. 38 | This is the central function of the package and represent the second step 39 | in the analytic framework implemented in the package \code{specr}. It estimates 40 | and returns respective parameters and estimates of models that were specified 41 | via \code{setup()}. 42 | } 43 | \details{ 44 | Empirical results are often contingent on analytical decisions that 45 | are equally defensible, often arbitrary, and motivated by different reasons. 46 | This decisions may introduce bias or at least variability. To this end, 47 | specification curve analyses (Simonsohn et al., 2020) or multiverse 48 | analyses (Steegen et al., 2016) refer to identifying the set of 49 | theoretically justified, statistically valid (and potentially also non-redundant 50 | specifications, fitting the "multiverse" of models represented by these 51 | specifications and extract relevant parameters often to display the results 52 | graphically as a so-called specification curve. This allows readers to 53 | identify consequential specifications decisions and how they affect the results 54 | or parameter of interest. 55 | 56 | \bold{Use of this function} 57 | 58 | A general overview is provided in the vignettes \code{vignette("specr")}. 59 | Generally, you create relevant specification using the function \code{setup()}. 60 | You then pass the resulting object of a class \code{specr.setup} to the 61 | present function \code{specr()} to run the specification curve analysis. 62 | Further note that the resulting object of class \code{specr.object} allows 63 | to use several generic function such as \code{summary()} or \code{plot()}. 64 | Use \code{methods(class = "specr.object")} for an overview on available 65 | methods and e.g., \code{?plot.specr.object} to view the dedicated help page. 66 | 67 | \bold{Parallelization} 68 | 69 | By default, the function fits models across all specifications sequentially 70 | (one after the other). If the data set is large, the models complex (e.g., 71 | large structural equation models, negative binomial models, or Bayesian models), 72 | and the number of specifications is large, it can make sense to parallelize 73 | these operations. One simply has to load the package \code{furrr} (which 74 | in turn, builds on \code{future}) up front. Then parallelizing the fitting process 75 | works as specified in the package description of \code{furr}/\code{future} by setting a 76 | "plan" before running \code{specr} such as: 77 | 78 | \code{plan(multisession, workers = 4)} 79 | 80 | However, there are many more ways to specifically set up the plan, including 81 | different strategy than \code{multisession}. For more information, see 82 | \code{vignette("parallelization")} and the 83 | \href{https://future.futureverse.org/reference/plan.html}{reference page} 84 | for \code{plan()}. 85 | 86 | \bold{Disclaimer} 87 | 88 | We do see a lot of value in investigating how analytical choices 89 | affect a statistical outcome of interest. However, we strongly caution 90 | against using specr as a tool to somehow arrive at a better estimate 91 | compared to a single model. Running a specification curve analysis 92 | does not make your findings any more reliable, valid or generalizable 93 | than a single analysis. The method is meant to inform about the effects 94 | of analytical choices on results, and not a better way to estimate a 95 | correlation or effect. 96 | } 97 | \examples{ 98 | # Example 1 ---- 99 | # Setup up typical specifications 100 | specs <- setup(data = example_data, 101 | y = c("y1", "y2"), 102 | x = c("x1", "x2"), 103 | model = "lm", 104 | controls = c("c1", "c2"), 105 | subsets = list(group1 = unique(example_data$group1))) 106 | 107 | # Run analysis (not parallelized) 108 | results <- specr(specs) 109 | 110 | # Summary of the results 111 | summary(results) 112 | 113 | 114 | # Example 2 ---- 115 | # Working without S3 classes 116 | specs2 <- setup(data = example_data, 117 | y = c("y1", "y2"), 118 | x = c("x1", "x2"), 119 | model = "lm", 120 | controls = "c1") 121 | 122 | # Working with tibbles 123 | specs_tibble <- as_tibble(specs2) # extract tibble from setup 124 | results2 <- specr(specs_tibble, 125 | data = example_data) # need to provide data! 126 | 127 | # Results (tibble instead of S3 class) 128 | head(results2) 129 | } 130 | \references{ 131 | \itemize{ 132 | \item Simonsohn, U., Simmons, J.P. & Nelson, L.D. (2020). Specification curve analysis. \emph{Nature Human Behaviour, 4}, 1208–1214. https://doi.org/10.1038/s41562-020-0912-z 133 | \item Steegen, S., Tuerlinckx, F., Gelman, A., & Vanpaemel, W. (2016). Increasing Transparency Through a Multiverse Analysis. \emph{Perspectives on Psychological Science, 11}(5), 702-712. https://doi.org/10.1177/1745691616658637 134 | } 135 | } 136 | \seealso{ 137 | \code{\link[=setup]{setup()}} for the first step of setting up the specifications. 138 | 139 | \code{\link[=summary.specr.object]{summary.specr.object()}} for how to summarize and inspect the results. 140 | 141 | \code{\link[=plot.specr.object]{plot.specr.object()}} for plotting results. 142 | } 143 | -------------------------------------------------------------------------------- /man/summarise_specs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summarise_specs.r 3 | \name{summarise_specs} 4 | \alias{summarise_specs} 5 | \title{Summarise specifications} 6 | \usage{ 7 | summarise_specs( 8 | df, 9 | ..., 10 | var = .data$estimate, 11 | stats = list(median = median, mad = mad, min = min, max = max, q25 = function(x) 12 | quantile(x, prob = 0.25), q75 = function(x) quantile(x, prob = 0.75)) 13 | ) 14 | } 15 | \arguments{ 16 | \item{df}{a data frame resulting from \code{run_specs()}.} 17 | 18 | \item{...}{one or more grouping variables (e.g., subsets, controls,...) that denote the available analytical choices.} 19 | 20 | \item{var}{which variable should be evaluated? Defaults to estimate (the effect sizes computed by \code{\link[=run_specs]{run_specs()}}).} 21 | 22 | \item{stats}{named vector or named list of summary functions (individually defined summary functions can included). If it is not named, placeholders (e.g., "fn1") will be used as column names.} 23 | } 24 | \value{ 25 | a \link[tibble:tibble-package]{tibble}. 26 | } 27 | \description{ 28 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 29 | This function is deprecated because the new version of specr uses a new analytic framework. 30 | In this framework, you can plot a similar figure simply by using the generic \code{plot()} function. 31 | This function allows to inspect results of the specification curves by returning a comparatively simple summary of the results. This summary can be produced for various specific analytical choices and customized summary functions. 32 | } 33 | \examples{ 34 | # Run specification curve analysis 35 | results <- run_specs(df = example_data, 36 | y = c("y1", "y2"), 37 | x = c("x1", "x2"), 38 | model = c("lm"), 39 | controls = c("c1", "c2"), 40 | subsets = list(group1 = unique(example_data$group1), 41 | group2 = unique(example_data$group2))) 42 | 43 | # overall summary 44 | summarise_specs(results) 45 | 46 | # Summary of specific analytical choices 47 | summarise_specs(results, # data frame 48 | x, y) # analytical choices 49 | 50 | # Summary of other parameters across several analytical choices 51 | summarise_specs(results, 52 | subsets, controls, 53 | var = p.value, 54 | stats = list(median = median, 55 | min = min, 56 | max = max)) 57 | 58 | # Unnamed vector instead of named list passed to `stats` 59 | summarise_specs(results, 60 | controls, 61 | stats = c(mean = mean, 62 | median = median)) 63 | 64 | } 65 | \seealso{ 66 | \code{\link[=plot_summary]{plot_summary()}} to visually investigate the affect of analytical choices. 67 | } 68 | -------------------------------------------------------------------------------- /man/summary.specr.boot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{summary.specr.boot} 4 | \alias{summary.specr.boot} 5 | \title{Summarizing the bootstrapped results} 6 | \usage{ 7 | \method{summary}{specr.boot}(x, group = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{specr.boot} object, resulting from calling \code{boot_null()}.} 11 | 12 | \item{group}{Variables indicating which variables to summarize the results by} 13 | 14 | \item{...}{further arguments passed to or from other methods (currently ignored).} 15 | } 16 | \value{ 17 | A tibble. 18 | } 19 | \description{ 20 | Generic summary function for an object of class \code{specr.boot} (resulting from 21 | \code{boot_null()}. Provides an approach to inference for specification curve analysis 22 | consists of obtaining the median effect estimated across all specifications, 23 | and then testing whether this median estimated effect is more extreme than 24 | would be expected if all specifications had a true effect of zero. 25 | } 26 | -------------------------------------------------------------------------------- /man/summary.specr.object.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{summary.specr.object} 4 | \alias{summary.specr.object} 5 | \title{Summarizing the Specification Curve Analysis} 6 | \usage{ 7 | \method{summary}{specr.object}( 8 | object, 9 | type = "default", 10 | group = NULL, 11 | var = .data$estimate, 12 | stats = list(median = median, mad = mad, min = min, max = max, q25 = function(x) 13 | quantile(x, prob = 0.25), q75 = function(x) quantile(x, prob = 0.75)), 14 | digits = 2, 15 | rows = 6, 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{object}{An object of class "specr", usually resulting of a call to \code{specr}.} 21 | 22 | \item{type}{Different aspects can be summarized and printed. See details for alternative summaries} 23 | 24 | \item{group}{In combination with \code{what = "curve"}, provide a vector of one or more variables (e.g., subsets, controls,...) that denote the available analytic choices to group summary of the estimate.} 25 | 26 | \item{var}{In combination with \code{what = "curve"}, unquoted name of parameter to be summarized. Defaults to estimate.} 27 | 28 | \item{stats}{Named vector or named list of summary functions (individually defined summary functions can included). If it is not named, placeholders (e.g., "fn1") will be used as column names.} 29 | 30 | \item{digits}{The number of digits to use when printing the specification table.} 31 | 32 | \item{rows}{The number of rows of the specification tibble that should be printed.} 33 | 34 | \item{...}{further arguments passed to or from other methods (currently ignored).} 35 | } 36 | \value{ 37 | A printed summary of an object of class \code{specr.object}. 38 | } 39 | \description{ 40 | \code{summary} method for class "specr". It provides a printed output including 41 | technical details (e.g., cores used, duration of the fitting process, number 42 | of specifications), a descriptive analysis of the overall specification curve, 43 | a descriptive summary of the resulting sample sizes, and a head of the results. 44 | } 45 | \examples{ 46 | # Setup up specifications (returns object of class "specr.setup") 47 | specs <- setup(data = example_data, 48 | y = c("y1", "y2"), 49 | x = c("x1", "x2"), 50 | model = "lm", 51 | controls = c("c1", "c2"), 52 | subsets = list(group1 = unique(example_data$group1))) 53 | 54 | # Run analysis (returns object of class "specr.object") 55 | results <- specr(specs) 56 | 57 | # Default summary of the "specr.object" 58 | summary(results) 59 | 60 | # Summarize the specification curve descriptively 61 | summary(results, type = "curve") 62 | 63 | # Grouping for certain analytical decisions 64 | summary(results, 65 | type = "curve", 66 | group = c("x", "y")) 67 | 68 | # Using customized functions 69 | summary(results, 70 | type = "curve", 71 | group = c("x", "group1"), 72 | stats = list(median = median, 73 | min = min, 74 | max = max)) 75 | } 76 | \seealso{ 77 | The function used to create the "specr.setup" object: \code{setup}. 78 | } 79 | -------------------------------------------------------------------------------- /man/summary.specr.setup.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generics.r 3 | \name{summary.specr.setup} 4 | \alias{summary.specr.setup} 5 | \title{Summarizing the Specifications Setup} 6 | \usage{ 7 | \method{summary}{specr.setup}(object, digits = 2, rows = 6, print.specs = TRUE, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class "specr.setup", usually, a result of a call to \code{setup}.} 11 | 12 | \item{digits}{The number of digits to use when printing the specification table.} 13 | 14 | \item{rows}{The number of rows of the specification tibble that should be printed.} 15 | 16 | \item{print.specs}{Logical value; if \code{TRUE}, a head of the specification tibble 17 | is returned and printed.} 18 | 19 | \item{...}{further arguments passed to or from other methods (currently ignored).} 20 | } 21 | \value{ 22 | A printed summary of an object of class \code{specr.setup}. 23 | } 24 | \description{ 25 | \code{summary} method for class "specr.setup". Provides a short summary of the 26 | created specifications (the "multiverse") that lists all analytic choices, prints 27 | the function used to extract the parameters from the model. Finally, if 28 | \code{print.specs = TRUE}, it also shows the head of the actual specification grid. 29 | } 30 | \examples{ 31 | # Setup specifications 32 | specs <- setup(data = example_data, 33 | x = c("x1", "x2"), 34 | y = c("y1", "y2"), 35 | model = c("lm", "glm"), 36 | controls = c("c1", "c2", "c3"), 37 | subsets = list(group3 = unique(example_data$group3))) 38 | 39 | # Summarize specifications 40 | summary(specs) 41 | } 42 | \seealso{ 43 | The function \code{\link[=setup]{setup()}}, which creates the "specr.setup" object. 44 | } 45 | -------------------------------------------------------------------------------- /specr.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: Sweave 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 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(specr) 3 | 4 | test_check("specr") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-generics.R: -------------------------------------------------------------------------------- 1 | context("generics") 2 | 3 | specs <- specr::setup(data = example_data, 4 | x = c("x1", "x2"), 5 | y = "y1", 6 | model = "lm", 7 | subsets = list(group1 = unique(example_data$group1)), 8 | controls = c("c1", "c2")) 9 | results <- specr(specs) 10 | 11 | # Test 1 12 | test_that("Function plot.specr.setup creates a ggplot", { 13 | p <- plot(specs) 14 | expect_is(p, "gg") 15 | }) 16 | 17 | 18 | # Test 2 19 | test_that("Function plot.specr.object creates a ggplot", { 20 | p <- plot(results) 21 | expect_is(p, "gg") 22 | }) 23 | 24 | 25 | # Test 3 26 | test_that("Function plot.specr.object with `type = 'curve'` creates a ggplot", { 27 | p <- plot(results, "curve") 28 | expect_is(p, "gg") 29 | }) 30 | 31 | # Test 4 32 | test_that("Function plot.specr.object with `type = 'choices'` creates a ggplot", { 33 | p <- plot(results, "choices") 34 | expect_is(p, "gg") 35 | }) 36 | 37 | 38 | # Test 5 39 | test_that("Function plot.specr.object with `type = 'choices'` creates a ggplot", { 40 | p <- plot(results, "boxplot") 41 | expect_is(p, "gg") 42 | }) 43 | 44 | 45 | # Test 4 46 | test_that("Function plot.specr.object with `type = 'choices'` creates a ggplot", { 47 | p <- plot(results, "choices") 48 | expect_is(p, "gg") 49 | }) 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tests/testthat/test-setup.R: -------------------------------------------------------------------------------- 1 | context("setup") 2 | 3 | # Test 1: 4 | 5 | test_that("setup returns an object of class specr.setup", { 6 | expect_is(specr::setup(data = example_data, 7 | x = c("x1", "x2"), 8 | y = c("y1", "y2"), 9 | model = "lm", 10 | controls = c("c1", "c2", "c3")), "specr.setup") 11 | }) 12 | 13 | # Test 2: 14 | 15 | test_that("setup requires a data set", { 16 | expect_error(specr::setup(x = c("x1", "x2"), 17 | y = c("y1", "y2"), 18 | model = "lm", 19 | controls = c("c1", "c2", "c3")), 20 | "You must provide the data set that should be used in the analyses.") 21 | }) 22 | 23 | # Test 3: 24 | 25 | test_that("setup requires an x variable", { 26 | expect_error(specr::setup(data = example_data, 27 | y = c("y1", "y2"), 28 | model = "lm", 29 | controls = c("c1", "c2", "c3"), 30 | simplify = TRUE), 31 | "You must specify at least one independent variable `x`.") 32 | }) 33 | 34 | # Test 4: 35 | 36 | test_that("setup requires a y variable", { 37 | expect_error(specr::setup(data = example_data, 38 | x = c("x1", "x2"), 39 | model = "lm", 40 | controls = c("c1", "c2", "c3"), 41 | simplify = TRUE), 42 | "You must specify at least one dependent variable `y`.") 43 | }) 44 | 45 | # Test 5: 46 | 47 | test_that("setup requires a model function", { 48 | expect_error(specr::setup(data = example_data, 49 | x = c("x1", "x2"), 50 | y = c("y1", "y2"), 51 | controls = c("c1", "c2", "c3"))) 52 | }) 53 | 54 | # Test 6a: 55 | 56 | test_that("setup does not accept duplicates in x", { 57 | expect_error(specr::setup(data = example_data, 58 | x = c("x1", "x2", "x2"), 59 | y = c("y1", "y2"), 60 | model = "lm", 61 | controls = c("c1", "c2", "c3")), 62 | "Duplicate values in x, y, model, and controls are not allowed.") 63 | }) 64 | 65 | # Test 6b: 66 | 67 | test_that("setup does not accept duplicates in y", { 68 | expect_error(specr::setup(data = example_data, 69 | x = c("x1", "x2"), 70 | y = c("y1", "y2", "y1"), 71 | model = "lm", 72 | controls = c("c1", "c2", "c3")), 73 | "Duplicate values in x, y, model, and controls are not allowed.") 74 | }) 75 | 76 | # Test6c: 77 | 78 | test_that("setup does not accept duplicates in models", { 79 | expect_error(specr::setup(data = example_data, 80 | x = c("x1", "x2"), 81 | y = c("y1", "y2"), 82 | model = c("lm", "lm", "glm"), 83 | controls = c("c1", "c2", "c3")), 84 | "Duplicate values in x, y, model, and controls are not allowed.") 85 | }) 86 | 87 | # Test6c: 88 | 89 | test_that("setup does not accept duplicates in controls", { 90 | expect_error(specr::setup(data = example_data, 91 | x = c("x1", "x2"), 92 | y = c("y1", "y2"), 93 | model = c("lm", "lm", "glm"), 94 | controls = c("c1", "c2", "c3", "c2", "c3")), 95 | "Duplicate values in x, y, model, and controls are not allowed.") 96 | }) 97 | 98 | # Test 7: 99 | 100 | test_that("setup creates all combinations", { 101 | specs <- specr::setup(data = example_data, 102 | x = c("x1", "x2"), 103 | y = c("y1", "y2"), 104 | model = "lm", 105 | subsets = list(group1 = unique(example_data$group1), 106 | group2 = unique(example_data$group2))) 107 | expect_equal(nrow(specs$specs), 108 | (nrow(dplyr::distinct(example_data, group1)) + 1) * 109 | (nrow(dplyr::distinct(example_data, group2)) + 1) * 110 | length(c("x1", "x2")) * 111 | length(c("y1", "y2"))) 112 | }) 113 | 114 | # Test 8: 115 | 116 | test_that("setup creates a formula for each specification", { 117 | specs <- specr::setup(data = example_data, 118 | x = c("x1", "x2"), 119 | y = c("y1", "y2"), 120 | model = "lm", 121 | controls = c("c1", "c2", "c3")) 122 | expect_true(all(!is.na(specs$specs$formula))) 123 | }) 124 | 125 | # Test 9: 126 | 127 | test_that("setup creates a model function for each specification", { 128 | specs <- specr::setup(data = example_data, 129 | x = c("x1", "x2"), 130 | y = c("y1", "y2"), 131 | model = "lm", 132 | controls = c("c1", "c2", "c3"), 133 | simplify = TRUE) 134 | expect_true(all(!is.na(specs$specs$model_function))) 135 | }) 136 | 137 | # Test 10: 138 | 139 | test_that("setup creates a subsets variable", { 140 | specs <- specr::setup(data = example_data, 141 | x = c("x1", "x2"), 142 | y = c("y1", "y2"), 143 | model = "lm", 144 | subsets = list(group1 = unique(example_data$group1)), 145 | controls = c("c1", "c2", "c3"), 146 | simplify = TRUE) 147 | expect_true(all(!is.na(specs$specs$subsets))) 148 | }) 149 | 150 | # Test 11: 151 | 152 | test_that("setup creates object of class `specr.setup`", { 153 | specs <- specr::setup(data = example_data, 154 | x = c("x1", "x2"), 155 | y = c("y1", "y2"), 156 | model = "lm", 157 | subsets = list(group1 = unique(example_data$group1)), 158 | controls = c("c1", "c2", "c3"), 159 | simplify = TRUE) 160 | expect_true(inherits(specs, "specr.setup")) 161 | }) 162 | -------------------------------------------------------------------------------- /tests/testthat/test-specr.R: -------------------------------------------------------------------------------- 1 | context("specr") 2 | 3 | specs <- specr::setup(data = example_data, 4 | x = c("x1", "x2"), 5 | y = c("y1"), 6 | model = "lm", 7 | controls = c("c1")) 8 | 9 | 10 | # test 1: check that the function returns an object of class 'specr.object' 11 | test_that("function returns an object of class 'specr.object'", { 12 | expect_true(class(specr(specs, workers = 1)) == "specr.object") 13 | }) 14 | 15 | # test 2: check that the function returns an error when no data is provided 16 | test_that("function returns an error when no data is provided", { 17 | expect_error(specr(as_tibble(specs), data = NULL), 18 | "You provided a tibble or data.frame with all the specifications. In that case, you also need to provide the data set that should be used for the analyses.") 19 | }) 20 | 21 | 22 | # test 3: check that the function returns an error when an incorrect object is provided 23 | test_that("function returns an error when an incorrect object is provided", { 24 | expect_error(specr(1)) 25 | }) 26 | 27 | # test 4: check that the function returns an object of class 'tibble' when no specr.setup is provided 28 | test_that("function returns an object of class 'tibble' when no specr.setup is provided", { 29 | expect_true(inherits(specr(as_tibble(specs), 30 | data = example_data, 31 | workers = 1), 32 | "tbl_df")) 33 | }) 34 | 35 | 36 | # test 4 37 | test_that("Specs and results have the same number of rows", { 38 | results <- specr(specs) 39 | expect_equal(nrow(specs), nrow(results)) 40 | }) 41 | 42 | # test 5 43 | test_that("Results include confidence intervals", { 44 | results <- specr(specs) 45 | expect_true(any(c("conf.low", "conf.high") %in% names(results$data))) 46 | }) 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/invest-spec.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Investigating specific specifications" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{Investigating specific specifications} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set( 12 | collapse = TRUE, 13 | comment = "#>", 14 | #fig.path = "man/figures/README-", 15 | out.width = "100%", 16 | fig.retina = 2 17 | ) 18 | ``` 19 | 20 | Per default, `specr()` summarizes individual specifications by using `broom::tidy()` and `broom::glance()`. For most cases, this provides a sufficient and appropriate summary of the relationship of interest and model characteristics. Sometimes, however, it might be useful to investigate specific models in more detail or to investigate a specific parameter that is not provided by the two functions (e.g., r-square). This vignette shows how to access individual models and extract further information from them. 21 | 22 | ```{r, message = F, warning = F} 23 | library(tidyverse) 24 | library(specr) 25 | library(performance) 26 | ``` 27 | 28 | ## Setup specifications with a specific extract function 29 | 30 | If we want to investigate individual models and particularly all aspects of that model, we need to create a custom extract function that also stores the entire model object in the result data frame. 31 | 32 | ```{r, message=F, warning = F} 33 | # Custom function 34 | tidy_new <- function(x) { 35 | fit <- broom::tidy(x, conf.int = TRUE) 36 | fit$res <- list(x) # Store model object 37 | return(fit) 38 | } 39 | 40 | # Run specification curve analysis 41 | specs <- setup(data = example_data, 42 | y = c("y1", "y2"), 43 | x = c("x1", "x2"), 44 | model = c("lm"), 45 | controls = c("c1", "c2"), 46 | subsets = list(group1 = unique(example_data$group1), 47 | group2 = unique(example_data$group2)), 48 | fun1 = tidy_new) 49 | 50 | results <- specr(specs) 51 | ``` 52 | 53 | 54 | ## Identify model(s) of interest 55 | 56 | For this example, we are going to look at two specific models (same independent variables, all controls, all participants, but different dependent variables). 57 | 58 | ```{r} 59 | (y_models <- results %>% 60 | as_tibble %>% 61 | filter(x == "x1", 62 | controls == "c1 + c2", 63 | subsets == "all")) %>% 64 | select(x:group2, estimate:res) 65 | ``` 66 | 67 | As you can see, the resulting tibble includes an additional column called `res`. This column includes the entire "model object" and we can use it to further investigate each model. 68 | 69 | ## Investigate models 70 | 71 | For example, we can now easily get a full summary of the models and compare individual coefficients and statistics. 72 | 73 | ```{r} 74 | y_models %>% 75 | pull(res) %>% 76 | map(summary) %>% 77 | map(coef) 78 | ``` 79 | 80 | Or we could get r-squared values for both models (here using the function `r2()` from the [performance](https://easystats.github.io/performance/) package). 81 | 82 | ```{r} 83 | y_models %>% 84 | pull(res) %>% 85 | map(r2) # r2 is include in the package "performance" 86 | ``` 87 | 88 | 89 | ## Some more examples 90 | 91 | This way, we can analyze or compare such statistics across several models. 92 | 93 | ```{r, fig.height=8, fig.width=10, message=F, warning = F} 94 | r2_results <- results %>% 95 | as_tibble %>% 96 | filter(subsets == "all") %>% 97 | mutate(r2 = map(res, r2), 98 | r2 = map_dbl(r2, 1)) %>% 99 | arrange(r2) 100 | 101 | r2_results %>% 102 | select(x:controls, r2) 103 | ``` 104 | 105 | And we can plot comparisons... 106 | 107 | ```{r} 108 | r2_results %>% 109 | arrange(r2) %>% 110 | mutate(rank = 1:n()) %>% 111 | ggplot(aes(x = rank, 112 | y = r2)) + 113 | geom_point() + 114 | geom_line() + 115 | theme_minimal() + 116 | theme(strip.text = element_blank(), 117 | axis.line = element_line("black", size = .5), 118 | axis.text = element_text(colour = "black")) 119 | ``` 120 | 121 | -------------------------------------------------------------------------------- /vignettes/man/figures/README-unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/vignettes/man/figures/README-unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /vignettes/man/figures/README-unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/vignettes/man/figures/README-unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /vignettes/multilevel-models.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Incorporating multilevel models" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{Incorporating multilevel models} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | knitr::opts_chunk$set( 12 | collapse = TRUE, 13 | comment = "#>", 14 | #fig.path = "man/figures/README-", 15 | out.width = "100%", 16 | fig.retina = 2 17 | ) 18 | ``` 19 | 20 | Many data are hierarchical and we want to acknowledge the nested structure in our models. Specr can easily estimate such multilevel models. We again have to write a customized function that we can pass first to `setup()` and the `specr()` will do the rest. 21 | 22 | For this example, we will us the `gapminder` data set that is included in the [gapminder](https://cran.r-project.org/package=gapminder) package. We quickly recode some variable to get more interpretable estimates. 23 | 24 | ```{r, message=F, warning = F} 25 | # Load packages 26 | library(tidyverse) 27 | library(specr) 28 | library(gapminder) 29 | library(lme4) 30 | 31 | # Recode some variables 32 | gapminder <- gapminder %>% 33 | mutate(gdpPercap_log = log(gdpPercap), 34 | pop = pop/1000) 35 | 36 | # Check data 37 | head(gapminder) 38 | ``` 39 | 40 | 41 | ## Simply adding a random effect structure 42 | 43 | For this example, we use the package [lme4](https://cran.r-project.org/package=lme4) and more specifically the function `lmer()` to estimate the multilevel model (more complex models such as poisson or negative binomial multilevel models can likewise be estimated). 44 | 45 | Based on the data set, we want to estimate the relationship between `gdpPercap` (GDP per capita) and `lifeExp` (life expectancy). Both variables are nested within both countries and years. We can simply add a respective random effect structure via the argument `add_to_formula`. This way, this will be automatically included in the formula of all specifications. Because `broom` doesn't provide a `tidy` function for `merMod`-objects resulting from `lme4::lmer()`, we need to add a new extraction function like so `fun1 = new_function`. Luckily, we can use the `broom.mixed` package, which agian provides a tidy function for such objects. 46 | 47 | ```{r} 48 | specs <- setup(data = gapminder, 49 | y = c("lifeExp"), 50 | x = c("gdpPercap_log"), 51 | model = c("lmer"), 52 | controls = "pop", 53 | fun1 = function(x) broom.mixed::tidy(x, conf.int = TRUE), 54 | add_to_formula = "(1|country) + (1|year)") 55 | 56 | # Check formula 57 | summary(specs) 58 | 59 | # Run analysis and inspect results 60 | results <- specr(specs) 61 | as_tibble(results) 62 | ``` 63 | 64 | 65 | ## Defining customatized multilevel functions 66 | 67 | Sometimes, we may not want to add one random effect structure to all models and instead explore more specific random structure (and even several different random effect structures). In this case, we create several customized lmer-functions that account for different nesting structures. 68 | 69 | ```{r} 70 | # Random intercept model (only country as grouping variable) 71 | lmer_ri_1 <- function(formula, data,...) { 72 | require(lme4) 73 | require(broom.mixed) 74 | formula <- paste(formula, "+ (1|country)") 75 | lmer(formula, data) 76 | } 77 | 78 | # Including random slopes (only country as grouping variable) 79 | lmer_rs_1 <- function(formula, data,...) { 80 | require(lme4) 81 | require(broom.mixed) 82 | slopevars <- unlist(strsplit(formula, " ~ "))[2] 83 | formula <- paste0(formula, "+ (1 + ", slopevars, "|country)" ) 84 | lmer(formula, data) 85 | } 86 | 87 | # Random intercept model (lifeExp is nested in both countries and years) 88 | lmer_ri_2 <- function(formula, data,...) { 89 | require(lme4) 90 | require(broom.mixed) 91 | formula <- paste0(formula, "+ (1|country) + (1|year)") 92 | lmer(formula, data) 93 | } 94 | 95 | # Including random slopes (intercept and slopes are nested in both countries and years) 96 | lmer_rs_2 <- function(formula, data,...) { 97 | require(lme4) 98 | require(broom.mixed) 99 | slopevars <- unlist(strsplit(formula, " ~ "))[2] 100 | formula <- paste0(formula, "+ (1 + ", slopevars, "|country) + (", slopevars, "|year)" ) 101 | lmer(formula, data) 102 | } 103 | ``` 104 | 105 | ### Setting up specifications 106 | 107 | We can now use these function to estimate these models. In this example, we investigate the influence of different nesting structures on the fixed effect between GDP per capita and life expectancy. 108 | 109 | ```{r, message=F, warning = F} 110 | # Setup specifications with customized functions 111 | specs <- setup(data = gapminder, 112 | y = c("lifeExp"), 113 | x = c("gdpPercap_log"), 114 | model = c("lmer_ri_1", "lmer_ri_2", 115 | "lmer_rs_1", "lmer_rs_2"), 116 | controls = "pop") 117 | 118 | # Check specifications 119 | summary(specs) 120 | ``` 121 | 122 | ### Fit the models 123 | 124 | Now, we can simply fit the models with `specr()` as we are used to. 125 | 126 | ```{r, warning = F, message = F, fig.height=8, fig.width=8} 127 | # Run analysis and plot results 128 | results <- specr(specs) 129 | plot(results) 130 | ``` 131 | 132 | -------------------------------------------------------------------------------- /vignettes/parallelization.Rmd.orig: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Using parallelization" 3 | output: rmarkdown::html_vignette 4 | vignette: > 5 | %\VignetteIndexEntry{Using parallelization} 6 | %\VignetteEngine{knitr::rmarkdown} 7 | %\VignetteEncoding{UTF-8} 8 | --- 9 | 10 | A major improvement in version 0.3.0 of specr is that we can parallelize the computations, which can reduce fitting time. For this, specr uses functions from the package [furrr](https://furrr.futureverse.org/). I suggest to check out the website of the package for further information. To be to use relevant functions, we load the package furrr upfront. 11 | 12 | Before we start to run some examples, bear in mind that using parallelization does not always mean that the computations are automatically faster. If the overall computation time is not very long, using parallelization may even lead to a longer fitting process as setting up several "workers" (essentially setting up procedures on several cores) produces a considerable "overhead". A true reduction in fitting time is thus only achieved when the data set is large, the number of specification are high, and the computed models are complex. I thus first simulate a comparatively large data set that allows to specify more than 1000 specifications. 13 | 14 | ```{r, message = F, warning = F} 15 | # Load packages 16 | library(tidyverse) 17 | library(specr) 18 | library(furrr) 19 | 20 | # Data generating function 21 | generate_data <- function(seed = 42, n = 1e5) { 22 | if (!is.na(seed)) set.seed(seed) 23 | dat <- tibble( 24 | x1 = rnorm(n), 25 | x2 = rnorm(n)+ 0.9*x1, 26 | x3 = rnorm(n)+ 0.9*x2, 27 | x4 = rnorm(n)+ 0.9*x3, 28 | y4 = rep(c(1, 0), times = n/2), 29 | y1 = rnorm(n) + x1*.1 * 0.9*y4, 30 | y2 = rnorm(n) + x1*.2, 31 | y3 = rnorm(n) + x1*.2 + -0.4*x2, 32 | c1 = rnorm(n) + x1*.3, 33 | c2 = rnorm(n), 34 | c3 = rnorm(n) + 0.9*c1, 35 | c4 = rnorm(n), 36 | group = sample(c("a", "b", "c", "d", "e"), n, replace = TRUE) 37 | ) 38 | } 39 | 40 | # Generate very large data set (n = 50,000, 2 MB on disk) 41 | dat <- generate_data(9) 42 | head(dat) 43 | ``` 44 | 45 | ## Simple parallelization without custom functions 46 | 47 | If we use standard model fitting function (e.g., "lm") that are included in the base package, parallelization is comparatively simple. We only need to load the package furrr and specify a "plan for how to resolve a future" (for more information see `?future::plan`). In this case, I am choosing `multisession` (resolve the computations separate R sessions running in the background on the same machine) and specify `workers = 4` so that it runs on 4 cores in parallel. 48 | 49 | ```{r} 50 | # Setup of specifications (number of specs = 1152) 51 | specs <- setup(data = dat, 52 | y = c("y1", "y2", "y3"), 53 | x = c("x1", "x2", "x3", "x4"), 54 | model = c("lm"), 55 | controls = c("c1", "c2", "c3", "c4"), 56 | subsets = list(group = unique(dat$group))) 57 | 58 | # Default: Sequential --- 59 | results_simple <- specr(specs) 60 | 61 | # Parallel: Multisession (only works when `furrr` is loaded!) 62 | plan(strategy = multisession, workers = 4) 63 | results_parall <- specr(specs) 64 | 65 | # Comparison 66 | cat("Sequential: ", results_simple$time, "\n", 67 | "Parallel: ", results_parall$time) 68 | ``` 69 | 70 | As we can see, the default (sequential) computation took around a minute (`r results_simple$time`) and the parallel computation about half a minute (`r results_parall$time`). 71 | 72 | We have to acknowledge that even with this comparatively large data set and more than 1,000 specifications, the reduction in time is maybe not too exciting. Thus, parallelization only makes sense if you have a truly large data set and thousands of specifications *or* the type of model you are estimating takes a really long time (e.g., a complex structural equation model, a negative binomial model, etc.). The true power of parallelization furthermore only come into play if you are using a considerable large number of cores. 73 | 74 | 75 | ## Parallelization with custom functions from different packages 76 | 77 | If we use a custom function, we need to make sure that this function is passed to the different workers. This can be done by specifying so called `furrr_options()`. We need to pass objects from the global environment (and potentially also packages) as shown below. Please note that we do not have to specify the "future plan" again, because have specified it already earlier in this session (see above). If we are unsure what plan is currently specified, we can simply run `plan()` and get some information about the current setup. 78 | 79 | As computation can take a long time, it would be nice if we would see some kind of progress indication. This can easily be done by simply adding the argument `.progress = TRUE` to `specr()`. This passes this argument to the `future_pmap()` function within `specr()` and prints a rudimentary progress bar during the fitting process. 80 | 81 | ```{r} 82 | # Custom function 83 | log_model <- function(formula, data) { 84 | glm(formula, data, family = binomial()) 85 | } 86 | 87 | # Setup specs 88 | specs <- setup(data = dat, 89 | y = c("y4"), 90 | x = c("x1", "x2", "x3"), 91 | model = c("log_model"), 92 | controls = c("c1", "c2"), 93 | subsets = list(group = unique(dat$group))) 94 | 95 | # Create furrr_options to be passed to specr() (only works if `furrr` is loaded) 96 | opts <- furrr_options( 97 | globals = list(log_model = log_model) 98 | ) 99 | 100 | # What "plan" is currently specified? 101 | plan() 102 | 103 | # Run results 104 | results_parall_2 <- specr(specs, 105 | .options = opts, # Pass ops to specr 106 | .progress = TRUE) # To add progress bar (not shown in output) 107 | 108 | # Summarize results 109 | summary(results_parall_2) 110 | ``` 111 | 112 | Note: In the technical details of the summary, we also always see how many cores were used and how long the fitting process has taken. 113 | 114 | At the end of our analysis, it makes sense to explicitly close multisession workers by switching the plan back to sequential. 115 | 116 | ```{r} 117 | plan(sequential) 118 | ``` 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /vignettes/simonsohn_inference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masurp/specr/92e9f659cedc6a0d825901b0eabdc790f24d1020/vignettes/simonsohn_inference.png --------------------------------------------------------------------------------