├── .Rbuildignore ├── .gitattributes ├── .github ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md └── workflows │ ├── R-CMD-check-hard.yaml │ ├── R-CMD-check.yaml │ ├── html-5-check.yaml │ ├── lint.yaml │ └── pkgdown.yml ├── .gitignore ├── .lintr ├── CRAN-SUBMISSION ├── DESCRIPTION ├── NAMESPACE ├── NEWS.md ├── R ├── S3-methods.R ├── color_utils.R ├── helpfunctions.R ├── html_print.R ├── html_print_utils.R ├── plot_diag_linear.R ├── plot_diag_stan.R ├── plot_frq.R ├── plot_gpt.R ├── plot_grid.R ├── plot_grpfrq.R ├── plot_kfold_cv.R ├── plot_likert.R ├── plot_model.R ├── plot_model_estimates.R ├── plot_models.R ├── plot_point_estimates.R ├── plot_residuals.R ├── plot_scatter.R ├── plot_stackfrq.R ├── plot_type_eff.R ├── plot_type_est.R ├── plot_type_int.R ├── plot_type_ranef.R ├── plot_type_slope.R ├── plot_xtab.R ├── save_plot.R ├── select_helpers.R ├── sjPlotAnova.R ├── sjPlotCorr.R ├── sjPlotDist.R ├── sjPlotPearsonsChi2Test.R ├── sjPlotPolynomials.R ├── sjPlotSetTheme.R ├── sjplot.R ├── sjplot_themes.R ├── tab_corr.R ├── tab_fa.R ├── tab_itemscale.R ├── tab_model.R ├── tab_pca.R ├── tab_stackfrq.R ├── tab_xtab.R ├── tidiers.R ├── utils.R ├── view_df.R └── zzz.R ├── README.md ├── _pkgdown.yml ├── cran-comments.md ├── data └── efc.RData ├── devel.Rproj ├── inst └── CITATION ├── man ├── dist_chisq.Rd ├── dist_f.Rd ├── dist_norm.Rd ├── dist_t.Rd ├── efc.Rd ├── figures │ └── logo.png ├── plot_frq.Rd ├── plot_gpt.Rd ├── plot_grid.Rd ├── plot_grpfrq.Rd ├── plot_kfold_cv.Rd ├── plot_likert.Rd ├── plot_model.Rd ├── plot_models.Rd ├── plot_residuals.Rd ├── plot_scatter.Rd ├── plot_stackfrq.Rd ├── plot_xtab.Rd ├── save_plot.Rd ├── set_theme.Rd ├── sjPlot-package.Rd ├── sjPlot-themes.Rd ├── sjp.aov1.Rd ├── sjp.chi2.Rd ├── sjp.corr.Rd ├── sjp.poly.Rd ├── sjplot.Rd ├── tab_corr.Rd ├── tab_df.Rd ├── tab_fa.Rd ├── tab_itemscale.Rd ├── tab_model.Rd ├── tab_pca.Rd ├── tab_stackfrq.Rd ├── tab_xtab.Rd └── view_df.Rd ├── sjPlot.code-workspace ├── tests ├── testthat.R └── testthat │ ├── test-plot_grpfrq.R │ ├── test-plot_model_std.R │ └── test-tab_model.R └── vignettes ├── blackwhitefigures.Rmd ├── custplot.Rmd ├── plot_interactions.Rmd ├── plot_likert_scales.Rmd ├── plot_marginal_effects.Rmd ├── plot_model_estimates.Rmd ├── sjtitemanalysis.Rmd ├── tab_bayes.Rmd ├── tab_mixed.Rmd ├── tab_model_estimates.Rmd ├── tab_model_robust.Rmd └── table_css.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.travis\.yml$ 4 | ^_pkgdown\.yml$ 5 | 6 | ^doc$ 7 | ^docs$ 8 | ^revdep$ 9 | ^Meta$ 10 | ^pkgdown$ 11 | ^.github$ 12 | 13 | \.code-workspace$ 14 | \.lintr$ 15 | ^CRAN-SUBMISSION$ 16 | ^cran-comments.md$ 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/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 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to sjmisc 2 | 3 | This outlines how to propose a change to sjmisc. 4 | 5 | ## Fixing typos 6 | 7 | Small typos or grammatical errors in documentation may be edited directly using the GitHub web interface, so long as the changes are made in the _source_ file. If you want to fix typos in the documentation, please edit the related `.R` file in the `R/` folder. Do _not_ edit an `.Rd` file in `man/`. 8 | 9 | ## Filing an issue 10 | 11 | The easiest way to propose a change or new feature is to file an issue. If you've found a 12 | 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). 13 | 14 | ## Pull request 15 | 16 | * Please create a Git branch for each pull request (PR). 17 | * Your contributed code should roughly follow the tidyverse [style guide](http://style.tidyverse.org). _Exceptions_ from this guide: if separated, use underscores for _function names_, but _dots_ for argument names. See as example [set_na()](https://strengejacke.github.io/sjmisc/reference/set_na.html). 18 | * sjmisc uses [roxygen2](https://cran.r-project.org/package=roxygen2), with 19 | [Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/markdown.html), 20 | for documentation. 21 | * sjmisc 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. 22 | * If your PR is a user-visible change, you may add a bullet to the top of `NEWS.md` describing the changes made. You may optionally add your GitHub username, and links to relevant issue(s)/PR(s). 23 | 24 | ## Code of Conduct 25 | 26 | 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 27 | abide by its terms. 28 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check-hard.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 | # 4 | # NOTE: This workflow only directly installs "hard" dependencies, i.e. Depends, 5 | # Imports, and LinkingTo dependencies. Notably, Suggests dependencies are never 6 | # installed, with the exception of testthat, knitr, and rmarkdown. The cache is 7 | # never used to avoid accidentally restoring a cache containing a suggested 8 | # dependency. 9 | on: 10 | push: 11 | branches: 12 | - master 13 | pull_request: 14 | branches: 15 | - master 16 | 17 | name: R-CMD-check-hard 18 | 19 | jobs: 20 | R-CMD-check: 21 | runs-on: ${{ matrix.config.os }} 22 | 23 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 24 | 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | config: 29 | - { os: ubuntu-latest, r: "release" } 30 | 31 | env: 32 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 33 | R_KEEP_PKG_SOURCE: yes 34 | 35 | steps: 36 | - uses: actions/checkout@v3 37 | 38 | # Always try to use the latest pandoc version 39 | # https://github.com/jgm/pandoc/releases 40 | - uses: r-lib/actions/setup-pandoc@v2 41 | with: 42 | pandoc-version: "2.19.2" 43 | 44 | - uses: r-lib/actions/setup-r@v2 45 | with: 46 | r-version: ${{ matrix.config.r }} 47 | http-user-agent: ${{ matrix.config.http-user-agent }} 48 | use-public-rspm: true 49 | 50 | - uses: r-lib/actions/setup-r-dependencies@v2 51 | with: 52 | pak-version: devel 53 | dependencies: '"hard"' 54 | cache: false 55 | extra-packages: | 56 | any::rcmdcheck 57 | any::testthat 58 | any::knitr 59 | any::rmarkdown 60 | needs: check 61 | 62 | - uses: r-lib/actions/check-r-package@v2 63 | with: 64 | upload-snapshots: true -------------------------------------------------------------------------------- /.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 | 4 | on: 5 | push: 6 | branches: 7 | - master 8 | pull_request: 9 | branches: 10 | - master 11 | 12 | name: R-CMD-check 13 | 14 | jobs: 15 | R-CMD-check: 16 | runs-on: ${{ matrix.config.os }} 17 | 18 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) ${{ matrix.config.locale }} 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | config: 24 | - { os: macOS-latest, r: "release" } 25 | - { os: macOS-latest, r: "oldrel" } 26 | 27 | - { os: windows-latest, r: "devel" } 28 | - { os: windows-latest, r: "release" } 29 | - { os: windows-latest, r: "oldrel" } 30 | 31 | - { os: ubuntu-latest, r: "devel" } 32 | - { os: ubuntu-latest, r: "release" } 33 | - { os: ubuntu-latest, r: "oldrel" } 34 | 35 | env: 36 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 37 | R_KEEP_PKG_SOURCE: yes 38 | _R_CHECK_CRAN_INCOMING_: false 39 | _R_CHECK_FORCE_SUGGESTS_: false 40 | 41 | steps: 42 | - name: Set locale 43 | if: matrix.config.locale == 'en_US' 44 | run: | 45 | sudo locale-gen en_US 46 | echo "LC_ALL=en_US" >> $GITHUB_ENV 47 | 48 | - uses: actions/checkout@v3 49 | 50 | # Always try to use the latest pandoc version 51 | # https://github.com/jgm/pandoc/releases 52 | - uses: r-lib/actions/setup-pandoc@v2 53 | with: 54 | pandoc-version: "2.19.2" 55 | 56 | - uses: r-lib/actions/setup-r@v2 57 | with: 58 | r-version: ${{ matrix.config.r }} 59 | http-user-agent: ${{ matrix.config.http-user-agent }} 60 | use-public-rspm: true 61 | 62 | # TODO: Check which of the ignore conditions are still relevant given the 63 | # current suggested dependencies and the minimum supported R version. 64 | # Update if anything out of date or not needed anymore. 65 | - uses: r-lib/actions/setup-r-dependencies@v2 66 | with: 67 | pak-version: devel 68 | extra-packages: | 69 | any::rcmdcheck 70 | needs: check 71 | 72 | # Don't error on "note" because if any of the suggested packages are not available 73 | # for a given R version, this generates a NOTE causing unnecessary build failure 74 | - uses: r-lib/actions/check-r-package@v2 75 | with: 76 | error-on: '"warning"' 77 | upload-snapshots: true 78 | -------------------------------------------------------------------------------- /.github/workflows/html-5-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: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | name: HTML5 check 12 | 13 | jobs: 14 | HTML5-check: 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | R_KEEP_PKG_SOURCE: yes 19 | steps: 20 | - uses: actions/checkout@v3 21 | 22 | - uses: r-lib/actions/setup-r@v2 23 | with: 24 | r-version: "devel" 25 | http-user-agent: "release" 26 | use-public-rspm: true 27 | 28 | - uses: r-lib/actions/setup-r-dependencies@v2 29 | with: 30 | pak-version: devel 31 | extra-packages: any::rcmdcheck, any::V8 32 | dependencies: "character()" 33 | 34 | - name: Install pdflatex 35 | run: sudo apt-get install texlive-latex-base texlive-fonts-recommended texlive-fonts-extra texlive-latex-extra 36 | 37 | - name: Install tidy 38 | run: sudo apt install tidy 39 | 40 | - uses: r-lib/actions/check-r-package@v2 41 | with: 42 | args: 'c("--as-cran", "--no-codoc", "--no-examples", "--no-tests", "--no-vignettes", "--no-build-vignettes", "--ignore-vignettes", "--no-install")' 43 | build_args: 'c("--no-build-vignettes")' 44 | error-on: '"note"' 45 | env: 46 | _R_CHECK_CRAN_INCOMING_REMOTE_: false 47 | _R_CHECK_CRAN_INCOMING_: false 48 | _R_CHECK_RD_XREFS_: false -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | name: lint 12 | 13 | jobs: 14 | lint: 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | steps: 19 | - uses: actions/checkout@v3 20 | 21 | - uses: r-lib/actions/setup-r@v2 22 | with: 23 | use-public-rspm: true 24 | 25 | - uses: r-lib/actions/setup-r-dependencies@v2 26 | with: 27 | pak-version: devel 28 | extra-packages: | 29 | r-lib/lintr 30 | EGAnet=?ignore-before-r=5.0.0 31 | local::. 32 | needs: lint 33 | 34 | # TODO: Revisit to remove some of these allowances after more important lints 35 | # have been removed. 36 | - name: Lint 37 | run: | 38 | library(lintr) 39 | lint_package(linters = linters_with_defaults( 40 | absolute_path_linter = NULL, 41 | commented_code_linter = NULL, 42 | cyclocomp_linter = cyclocomp_linter(50), 43 | implicit_integer_linter = NULL, 44 | line_length_linter(120), 45 | nonportable_path_linter = NULL, 46 | object_name_linter = NULL, 47 | object_length_linter(50), 48 | object_usage_linter = NULL, 49 | todo_comment_linter = NULL, 50 | extraction_operator_linter = NULL, 51 | unneeded_concatenation_linter(allow_single_expression = FALSE), 52 | defaults = linters_with_tags(tags = NULL) 53 | )) 54 | shell: Rscript {0} -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v2 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::pkgdown, local::. 34 | needs: website 35 | 36 | - name: Build site 37 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 38 | shell: Rscript {0} 39 | 40 | - name: Deploy to GitHub pages 🚀 41 | if: github.event_name != 'pull_request' 42 | uses: JamesIves/github-pages-deploy-action@4.1.4 43 | with: 44 | clean: false 45 | branch: gh-pages 46 | folder: docs 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | 4 | # Example code in package build process 5 | *-Ex.R 6 | 7 | # R data files from past sessions 8 | .Rdata 9 | 10 | # ========================= 11 | # Operating System Files 12 | # ========================= 13 | 14 | # OSX 15 | # ========================= 16 | 17 | .DS_Store 18 | .AppleDouble 19 | .LSOverride 20 | 21 | # Icon must end with two \r 22 | Icon 23 | 24 | 25 | # Thumbnails 26 | ._* 27 | 28 | # Files that might appear on external disk 29 | .Spotlight-V100 30 | .Trashes 31 | 32 | # Directories potentially created on remote AFP share 33 | .AppleDB 34 | .AppleDesktop 35 | Network Trash Folder 36 | Temporary Items 37 | .apdisk 38 | 39 | # Windows 40 | # ========================= 41 | 42 | # Windows image file caches 43 | Thumbs.db 44 | ehthumbs.db 45 | 46 | # Folder config file 47 | Desktop.ini 48 | 49 | # Recycle Bin used on file shares 50 | $RECYCLE.BIN/ 51 | 52 | # Windows Installer files 53 | *.cab 54 | *.msi 55 | *.msm 56 | *.msp 57 | .Rproj.user 58 | 59 | 60 | inst/doc 61 | revdep 62 | vignettes/*.html 63 | Rplots.pdf 64 | doc 65 | Meta 66 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | linters: linters_with_defaults( 2 | absolute_path_linter = NULL, 3 | commented_code_linter = NULL, 4 | cyclocomp_linter = cyclocomp_linter(25), 5 | extraction_operator_linter = NULL, 6 | implicit_integer_linter = NULL, 7 | line_length_linter(120), 8 | namespace_linter = NULL, 9 | nonportable_path_linter = NULL, 10 | object_name_linter = NULL, 11 | object_length_linter(50), 12 | object_usage_linter = NULL, 13 | todo_comment_linter = NULL, 14 | undesirable_function_linter(c("mapply" = NA, "sapply" = NA, "setwd" = NA)), 15 | undesirable_operator_linter = NULL, 16 | defaults = linters_with_tags(tags = NULL) 17 | ) 18 | -------------------------------------------------------------------------------- /CRAN-SUBMISSION: -------------------------------------------------------------------------------- 1 | Version: 2.8.11 2 | Date: 2022-08-07 07:24:52 UTC 3 | SHA: 692925cba9467141de97b865ea3a983dcd8812cf 4 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: sjPlot 2 | Type: Package 3 | Encoding: UTF-8 4 | Title: Data Visualization for Statistics in Social Science 5 | Version: 2.8.17 6 | Authors@R: c( 7 | person("Daniel", "Lüdecke", email = "d.luedecke@uke.de", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-8895-3206")), 8 | person("Alexander", "Bartel", role = "ctb", comment = c(ORCID = "0000-0002-1280-6138")), 9 | person("Carsten", "Schwemmer", email = "carsten.schwemmer@uni-bamberg.de", role = "ctb"), 10 | person(given = "Chuck", family = "Powell", role = "ctb", email = "ibecav@gmail.com", comment = c(ORCID = "0000-0002-3606-2188")), 11 | person(given = "Amir", family = "Djalovski", role = "ctb", email = "Amir.DJV@gmail.com"), 12 | person(given = "Johannes", family = "Titz", role = "ctb", email = "johannes@titz.science", comment = c(ORCID = "0000-0002-1102-5719"))) 13 | Maintainer: Daniel Lüdecke 14 | Description: Collection of plotting and table output functions for data 15 | visualization. Results of various statistical analyses (that are commonly used 16 | in social sciences) can be visualized using this package, including simple and 17 | cross tabulated frequencies, histograms, box plots, (generalized) linear models, 18 | mixed effects models, principal component analysis and correlation matrices, 19 | cluster analyses, scatter plots, stacked scales, effects plots of regression 20 | models (including interaction terms) and much more. This package supports 21 | labelled data. 22 | License: GPL-3 23 | Depends: 24 | R (>= 3.6) 25 | Imports: 26 | graphics, 27 | grDevices, 28 | stats, 29 | utils, 30 | bayestestR, 31 | datawizard, 32 | dplyr, 33 | ggeffects, 34 | ggplot2 (>= 3.2.0), 35 | knitr, 36 | insight, 37 | MASS, 38 | parameters, 39 | performance, 40 | purrr, 41 | rlang, 42 | scales, 43 | sjlabelled (>= 1.1.2), 44 | sjmisc (>= 2.8.2), 45 | sjstats (>= 0.17.8), 46 | tidyr (>= 1.0.0) 47 | Suggests: 48 | brms, 49 | car, 50 | clubSandwich, 51 | cluster, 52 | cowplot, 53 | effects, 54 | haven, 55 | GPArotation, 56 | ggrepel, 57 | glmmTMB, 58 | gridExtra, 59 | ggridges, 60 | httr, 61 | lme4, 62 | nFactors, 63 | pscl, 64 | psych, 65 | rmarkdown, 66 | rstanarm, 67 | sandwich, 68 | splines, 69 | survey, 70 | TMB, 71 | testthat 72 | URL: https://strengejacke.github.io/sjPlot/ 73 | BugReports: https://github.com/strengejacke/sjPlot/issues 74 | RoxygenNote: 7.3.2 75 | VignetteBuilder: knitr 76 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(knit_print,sjTable) 4 | S3method(knit_print,sjt_descr) 5 | S3method(knit_print,sjt_frq) 6 | S3method(knit_print,sjt_grpdescr) 7 | S3method(knit_print,sjt_grpmean) 8 | S3method(knit_print,sjt_grpmeans) 9 | S3method(knit_print,sjt_mwu) 10 | S3method(knit_print,sjt_reliab) 11 | S3method(print,sjTable) 12 | S3method(print,sjt_descr) 13 | S3method(print,sjt_equi_test) 14 | S3method(print,sjt_frq) 15 | S3method(print,sjt_grpdescr) 16 | S3method(print,sjt_grpmean) 17 | S3method(print,sjt_grpmeans) 18 | S3method(print,sjt_mwu) 19 | S3method(print,sjt_reliab) 20 | export(css_theme) 21 | export(dist_chisq) 22 | export(dist_f) 23 | export(dist_norm) 24 | export(dist_t) 25 | export(font_size) 26 | export(get_model_data) 27 | export(label_angle) 28 | export(legend_style) 29 | export(plot_frq) 30 | export(plot_gpt) 31 | export(plot_grid) 32 | export(plot_grpfrq) 33 | export(plot_kfold_cv) 34 | export(plot_likert) 35 | export(plot_model) 36 | export(plot_models) 37 | export(plot_residuals) 38 | export(plot_scatter) 39 | export(plot_stackfrq) 40 | export(plot_xtab) 41 | export(save_plot) 42 | export(scale_color_sjplot) 43 | export(scale_fill_sjplot) 44 | export(set_theme) 45 | export(show_sjplot_pals) 46 | export(sjp.aov1) 47 | export(sjp.chi2) 48 | export(sjp.corr) 49 | export(sjp.poly) 50 | export(sjplot) 51 | export(sjplot_pal) 52 | export(sjt.itemanalysis) 53 | export(sjt.xtab) 54 | export(sjtab) 55 | export(tab_corr) 56 | export(tab_df) 57 | export(tab_dfs) 58 | export(tab_fa) 59 | export(tab_itemscale) 60 | export(tab_model) 61 | export(tab_pca) 62 | export(tab_stackfrq) 63 | export(tab_xtab) 64 | export(theme_538) 65 | export(theme_blank) 66 | export(theme_sjplot) 67 | export(theme_sjplot2) 68 | export(view_df) 69 | import(ggplot2) 70 | importFrom(dplyr,"%>%") 71 | importFrom(dplyr,arrange) 72 | importFrom(dplyr,bind_rows) 73 | importFrom(dplyr,case_when) 74 | importFrom(dplyr,filter) 75 | importFrom(dplyr,group_by) 76 | importFrom(dplyr,group_modify) 77 | importFrom(dplyr,group_vars) 78 | importFrom(dplyr,if_else) 79 | importFrom(dplyr,mutate) 80 | importFrom(dplyr,n_distinct) 81 | importFrom(dplyr,select) 82 | importFrom(dplyr,slice) 83 | importFrom(dplyr,summarize) 84 | importFrom(ggeffects,ggeffect) 85 | importFrom(ggeffects,ggpredict) 86 | importFrom(grDevices,axisTicks) 87 | importFrom(grDevices,cm) 88 | importFrom(grDevices,colorRampPalette) 89 | importFrom(grDevices,dev.off) 90 | importFrom(grDevices,jpeg) 91 | importFrom(grDevices,png) 92 | importFrom(grDevices,rgb) 93 | importFrom(grDevices,svg) 94 | importFrom(grDevices,tiff) 95 | importFrom(graphics,plot) 96 | importFrom(insight,has_intercept) 97 | importFrom(insight,is_multivariate) 98 | importFrom(insight,model_info) 99 | importFrom(knitr,asis_output) 100 | importFrom(knitr,knit_print) 101 | importFrom(performance,cronbachs_alpha) 102 | importFrom(performance,performance_aic) 103 | importFrom(performance,performance_aicc) 104 | importFrom(purrr,as_vector) 105 | importFrom(purrr,flatten_chr) 106 | importFrom(purrr,map) 107 | importFrom(purrr,map_chr) 108 | importFrom(purrr,map_dbl) 109 | importFrom(purrr,map_df) 110 | importFrom(purrr,map_if) 111 | importFrom(purrr,map_lgl) 112 | importFrom(purrr,pmap) 113 | importFrom(rlang,.data) 114 | importFrom(rlang,enquo) 115 | importFrom(rlang,quo_name) 116 | importFrom(scales,brewer_pal) 117 | importFrom(scales,grey_pal) 118 | importFrom(scales,percent) 119 | importFrom(sjlabelled,copy_labels) 120 | importFrom(sjlabelled,drop_labels) 121 | importFrom(sjlabelled,get_label) 122 | importFrom(sjlabelled,get_labels) 123 | importFrom(sjlabelled,get_values) 124 | importFrom(sjlabelled,set_labels) 125 | importFrom(sjmisc,add_variables) 126 | importFrom(sjmisc,frq) 127 | importFrom(sjmisc,group_labels) 128 | importFrom(sjmisc,group_var) 129 | importFrom(sjmisc,is_empty) 130 | importFrom(sjmisc,is_even) 131 | importFrom(sjmisc,is_float) 132 | importFrom(sjmisc,is_num_fac) 133 | importFrom(sjmisc,to_value) 134 | importFrom(sjmisc,trim) 135 | importFrom(sjmisc,var_type) 136 | importFrom(sjmisc,word_wrap) 137 | importFrom(sjstats,cramer) 138 | importFrom(sjstats,crosstable_statistics) 139 | importFrom(sjstats,phi) 140 | importFrom(sjstats,table_values) 141 | importFrom(stats,aov) 142 | importFrom(stats,binomial) 143 | importFrom(stats,chisq.test) 144 | importFrom(stats,coef) 145 | importFrom(stats,complete.cases) 146 | importFrom(stats,confint) 147 | importFrom(stats,cor) 148 | importFrom(stats,cor.test) 149 | importFrom(stats,dchisq) 150 | importFrom(stats,deviance) 151 | importFrom(stats,df) 152 | importFrom(stats,dnorm) 153 | importFrom(stats,dt) 154 | importFrom(stats,fisher.test) 155 | importFrom(stats,fitted) 156 | importFrom(stats,ftable) 157 | importFrom(stats,glm) 158 | importFrom(stats,kruskal.test) 159 | importFrom(stats,lm) 160 | importFrom(stats,loess) 161 | importFrom(stats,logLik) 162 | importFrom(stats,na.omit) 163 | importFrom(stats,na.pass) 164 | importFrom(stats,pchisq) 165 | importFrom(stats,pf) 166 | importFrom(stats,pnorm) 167 | importFrom(stats,poly) 168 | importFrom(stats,ppoints) 169 | importFrom(stats,prcomp) 170 | importFrom(stats,predict) 171 | importFrom(stats,pt) 172 | importFrom(stats,qchisq) 173 | importFrom(stats,qf) 174 | importFrom(stats,qnorm) 175 | importFrom(stats,qt) 176 | importFrom(stats,quantile) 177 | importFrom(stats,reshape) 178 | importFrom(stats,residuals) 179 | importFrom(stats,rstudent) 180 | importFrom(stats,sd) 181 | importFrom(stats,summary.lm) 182 | importFrom(stats,weighted.mean) 183 | importFrom(stats,xtabs) 184 | importFrom(tidyr,gather) 185 | importFrom(tidyr,nest) 186 | importFrom(tidyr,spread) 187 | importFrom(utils,browseURL) 188 | importFrom(utils,setTxtProgressBar) 189 | importFrom(utils,txtProgressBar) 190 | -------------------------------------------------------------------------------- /R/color_utils.R: -------------------------------------------------------------------------------- 1 | col_check2 <- function(geom.colors, collen) { 2 | # -------------------------------------------- 3 | # check color argument 4 | # -------------------------------------------- 5 | # check for corrct color argument 6 | if (!is.null(geom.colors)) { 7 | # check for color brewer palette 8 | if (is.brewer.pal(geom.colors[1])) { 9 | geom.colors <- scales::brewer_pal(palette = geom.colors[1])(collen) 10 | } else if (is.sjplot.pal(geom.colors[1])) { 11 | geom.colors <- get_sjplot_colorpalette(geom.colors[1], collen) 12 | # do we have correct amount of colours? 13 | } else if (geom.colors[1] == "gs") { 14 | geom.colors <- scales::grey_pal()(collen) 15 | # do we have correct amount of colours? 16 | } else if (geom.colors[1] == "bw") { 17 | geom.colors <- rep("black", times = collen) 18 | # do we have correct amount of colours? 19 | } else if (length(geom.colors) > collen) { 20 | # shorten palette 21 | geom.colors <- geom.colors[1:collen] 22 | } else if (length(geom.colors) < collen) { 23 | # repeat color palette 24 | geom.colors <- rep(geom.colors, times = collen) 25 | # shorten to required length 26 | geom.colors <- geom.colors[1:collen] 27 | } 28 | } else { 29 | geom.colors <- scales::brewer_pal(palette = "Set1")(collen) 30 | } 31 | 32 | geom.colors 33 | } 34 | 35 | 36 | # check whether a color value is indicating 37 | # a color brewer palette 38 | is.brewer.pal <- function(pal) { 39 | bp.seq <- c("BuGn", "BuPu", "GnBu", "OrRd", "PuBu", "PuBuGn", "PuRd", "RdPu", 40 | "YlGn", "YlGnBu", "YlOrBr", "YlOrRd", "Blues", "Greens", "Greys", 41 | "Oranges", "Purples", "Reds") 42 | bp.div <- c("BrBG", "PiYG", "PRGn", "PuOr", "RdBu", "RdGy", "RdYlBu", 43 | "RdYlGn", "Spectral") 44 | bp.qul <- c("Accent", "Dark2", "Paired", "Pastel1", "Pastel2", "Set1", 45 | "Set2", "Set3") 46 | bp <- c(bp.seq, bp.div, bp.qul) 47 | pal %in% bp 48 | } 49 | 50 | 51 | is.sjplot.pal <- function(pal) { 52 | pal %in% names(sjplot_colors) 53 | } 54 | 55 | 56 | get_sjplot_colorpalette <- function(pal, len) { 57 | col <- sjplot_colors[[pal]] 58 | 59 | if (len > length(col)) { 60 | warning("More colors requested than length of color palette.", call. = F) 61 | len <- length(col) 62 | } 63 | 64 | col[1:len] 65 | } 66 | -------------------------------------------------------------------------------- /R/plot_diag_stan.R: -------------------------------------------------------------------------------- 1 | plot_diag_stan <- function(model, geom.colors, axis.lim, facets, axis.labels, ...) { 2 | 3 | # check some defaults 4 | if (missing(facets)) facets <- TRUE 5 | 6 | alpha <- .3 7 | scale <- .9 8 | 9 | 10 | if (inherits(model, "brmsfit")) { 11 | 12 | # check if brms can be loaded 13 | 14 | if (!requireNamespace("brms", quietly = TRUE)) 15 | stop("Package `brms` needs to be loaded first!", call. = F) 16 | 17 | # check if prior sample are available 18 | 19 | d2 <- brms::prior_samples(model) 20 | 21 | if (is.null(d2)) 22 | stop("No prior-samples found. Please use option `sample_prior = TRUE` when fitting the model.", call. = FALSE) 23 | 24 | 25 | # get samples from posterior and prior 26 | 27 | d2 <- dplyr::select( 28 | d2, 29 | string_starts_with("b_", colnames(d2)), 30 | -string_starts_with("b_Intercept", colnames(d2)) 31 | ) 32 | 33 | 34 | d1 <- brms::posterior_samples(model) 35 | 36 | d1 <- dplyr::select( 37 | d1, 38 | string_starts_with("b_", colnames(d1)), 39 | -string_starts_with("b_Intercept", colnames(d1)) 40 | ) 41 | 42 | } else if (inherits(model, c("stanreg", "stanfit"))) { 43 | 44 | # check if rstanarm can be loaded 45 | if (!requireNamespace("rstanarm", quietly = TRUE)) 46 | stop("Package `rstanarm` needs to be loaded first!", call. = F) 47 | 48 | 49 | # get samples from posterior and prior 50 | 51 | prior <- suppressWarnings( 52 | stats::update(model, prior_PD = TRUE, refresh = -1, iter = 2000, chains = 2) 53 | ) 54 | 55 | d1 <- as.data.frame(model) 56 | d2 <- as.data.frame(prior) 57 | 58 | 59 | # remove intercept from output for ridgeline plot. 60 | # this would increase the range of the scale too much 61 | 62 | if (obj_has_name(d1, "(Intercept)")) 63 | d1 <- dplyr::select(d1, -.data$`(Intercept)`) 64 | 65 | if (obj_has_name(d2, "(Intercept)")) 66 | d2 <- dplyr::select(d2, -.data$`(Intercept)`) 67 | 68 | if (obj_has_name(d1, "sigma")) 69 | d1 <- dplyr::select(d1, -.data$sigma) 70 | 71 | if (obj_has_name(d2, "sigma")) 72 | d2 <- dplyr::select(d2, -.data$sigma) 73 | 74 | d1 <- dplyr::select(d1, -string_starts_with("b[(Intercept)", colnames(d1))) 75 | d2 <- dplyr::select(d2, -string_starts_with("b[(Intercept)", colnames(d2))) 76 | d1 <- dplyr::select(d1, -string_starts_with("Sigma[", colnames(d1))) 77 | d2 <- dplyr::select(d2, -string_starts_with("Sigma[", colnames(d2))) 78 | } 79 | 80 | 81 | # grouping variable 82 | 83 | d1$Sample <- "Posterior" 84 | d2$Sample <- "Prior" 85 | 86 | gather.cols <- 1:(ncol(d1) - 1) 87 | 88 | # join data frames and convert to long format 89 | 90 | pp <- dplyr::bind_rows(d1, d2) %>% 91 | tidyr::gather(key = "Term", value = "Estimate", !! gather.cols) 92 | 93 | 94 | # additional arguments? 95 | add.args <- lapply(match.call(expand.dots = F)$`...`, function(x) x) 96 | if ("alpha" %in% names(add.args)) alpha <- eval(add.args[["alpha"]]) 97 | if ("scale" %in% names(add.args)) scale <- eval(add.args[["scale"]]) 98 | 99 | 100 | if (!facets && requireNamespace("ggridges", quietly = TRUE)) { 101 | p <- ggplot(pp, aes_string(y = "Term", x = "Estimate", fill = "Sample")) + 102 | ggridges::geom_density_ridges2(alpha = alpha, rel_min_height = .005, scale = scale) + 103 | scale_fill_manual(values = col_check2(geom.colors, 2)) 104 | } else { 105 | 106 | p <- ggplot(pp, aes_string(x = "Estimate", fill = "Sample")) + 107 | geom_density(alpha = alpha) + 108 | scale_fill_manual(values = col_check2(geom.colors, 2)) 109 | 110 | if (!is.null(axis.labels) && !is.null(names(axis.labels))) { 111 | p <- p + facet_wrap(~Term, scales = "free", labeller = labeller(.default = label_value, Term = axis.labels)) 112 | } else { 113 | p <- p + facet_wrap(~Term, scales = "free") 114 | } 115 | } 116 | 117 | 118 | if (!is.null(axis.lim)) 119 | p <- p + scale_x_continuous(limits = axis.lim) 120 | 121 | 122 | p + xlab("Distribution") 123 | } 124 | 125 | -------------------------------------------------------------------------------- /R/plot_grid.R: -------------------------------------------------------------------------------- 1 | #' @title Arrange list of plots as grid 2 | #' @name plot_grid 3 | #' 4 | #' @description Plot multiple ggplot-objects as a grid-arranged single plot. 5 | #' 6 | #' @param x A list of ggplot-objects. See 'Details'. 7 | #' @param margin A numeric vector of length 4, indicating the top, right, bottom 8 | #' and left margin for each plot, in centimetres. 9 | #' @param tags Add tags to your subfigures. Can be \code{TRUE} (letter tags) 10 | #' or character vector containing tags labels. 11 | #' 12 | #' @return An object of class \code{gtable}. 13 | #' 14 | #' @details This function takes a \code{list} of ggplot-objects as argument. 15 | #' Plotting functions of this package that produce multiple plot 16 | #' objects (e.g., when there is an argument \code{facet.grid}) usually 17 | #' return multiple plots as list (the return value is named \code{plot.list}). 18 | #' To arrange these plots as grid as a single plot, use \code{plot_grid}. 19 | #' 20 | #' @examples 21 | #' if (require("dplyr") && require("gridExtra")) { 22 | #' library(ggeffects) 23 | #' data(efc) 24 | #' 25 | #' # fit model 26 | #' fit <- glm( 27 | #' tot_sc_e ~ c12hour + e17age + e42dep + neg_c_7, 28 | #' data = efc, 29 | #' family = poisson 30 | #' ) 31 | #' 32 | #' # plot marginal effects for each predictor, each as single plot 33 | #' p1 <- ggpredict(fit, "c12hour") %>% 34 | #' plot(show_y_title = FALSE, show_title = FALSE) 35 | #' p2 <- ggpredict(fit, "e17age") %>% 36 | #' plot(show_y_title = FALSE, show_title = FALSE) 37 | #' p3 <- ggpredict(fit, "e42dep") %>% 38 | #' plot(show_y_title = FALSE, show_title = FALSE) 39 | #' p4 <- ggpredict(fit, "neg_c_7") %>% 40 | #' plot(show_y_title = FALSE, show_title = FALSE) 41 | #' 42 | #' # plot grid 43 | #' plot_grid(list(p1, p2, p3, p4)) 44 | #' 45 | #' # plot grid 46 | #' plot_grid(list(p1, p2, p3, p4), tags = TRUE) 47 | #' } 48 | #' @export 49 | plot_grid <- function(x, margin = c(1, 1, 1, 1), tags = NULL) { 50 | # check package availability ----- 51 | if (!requireNamespace("gridExtra", quietly = TRUE)) { 52 | stop("Package `gridExtra` needed for this function to work. Please install it.", call. = F) 53 | } 54 | 55 | # if user did not pass plot.list value, but the complete object returned 56 | # by sjPlot-functions, get plot-list then 57 | if (!inherits(x, "list") || inherits(x, "sjPlot")) x <- x[["plot.list"]] 58 | 59 | # add margin to each plot, so no axis labels are cropped 60 | x <- lapply(x, function(pl) { 61 | pl + theme(plot.margin = unit(margin, "cm")) 62 | }) 63 | 64 | tags_labels <- NULL 65 | 66 | # Add tags 67 | if (isTRUE(tags) || is.null(tags)) { 68 | tags_labels = LETTERS 69 | } else if (length(tags) < length(x)) { 70 | insight::format_warning("Not enough tags labels in list. Using letters instead.") 71 | tags_labels = LETTERS 72 | } else{ 73 | tags_labels = tags 74 | } 75 | 76 | if (!is.null(tags_labels)) { 77 | for (i in 1:length(x)) { 78 | x[[i]] <- x[[i]] + labs(tag = tags_labels[i]) 79 | } 80 | } 81 | 82 | 83 | # compute amount of columns and rows 84 | ncol <- round(sqrt(length(x))) 85 | nrow <- ceiling(length(x) / ncol) 86 | 87 | f <- eval(bquote(gridExtra::"grid.arrange")) 88 | do.call(f, c(x, nrow = nrow, ncol = ncol)) 89 | } 90 | -------------------------------------------------------------------------------- /R/plot_kfold_cv.R: -------------------------------------------------------------------------------- 1 | #' @title Plot model fit from k-fold cross-validation 2 | #' @name plot_kfold_cv 3 | #' 4 | #' @description This function plots the aggregated residuals of k-fold cross-validated 5 | #' models against the outcome. This allows to evaluate how the model performs 6 | #' according over- or underestimation of the outcome. 7 | #' 8 | #' @param data A data frame, used to split the data into \code{k} training-test-pairs. 9 | #' @param formula A model formula, used to fit linear models (\code{\link[stats]{lm}}) 10 | #' over all \code{k} training data sets. Use \code{fit} to specify a 11 | #' fitted model (also other models than linear models), which will be used 12 | #' to compute cross validation. If \code{fit} is not missing, \code{formula} 13 | #' will be ignored. 14 | #' @param k Number of folds. 15 | #' @param fit Model object, which will be used to compute cross validation. If 16 | #' \code{fit} is not missing, \code{formula} will be ignored. Currently, 17 | #' only linear, poisson and negative binomial regression models are supported. 18 | #' 19 | #' @details This function, first, generates \code{k} cross-validated test-training 20 | #' pairs and 21 | #' fits the same model, specified in the \code{formula}- or \code{fit}- 22 | #' argument, over all training data sets. \cr \cr 23 | #' Then, the test data is used to predict the outcome from all 24 | #' models that have been fit on the training data, and the residuals 25 | #' from all test data is plotted against the observed values (outcome) 26 | #' from the test data (note: for poisson or negative binomial models, the 27 | #' deviance residuals are calculated). This plot can be used to validate the model 28 | #' and see, whether it over- (residuals > 0) or underestimates 29 | #' (residuals < 0) the model's outcome. 30 | #' 31 | #' @note Currently, only linear, poisson and negative binomial regression models are supported. 32 | #' 33 | #' @examples 34 | #' data(efc) 35 | #' 36 | #' plot_kfold_cv(efc, neg_c_7 ~ e42dep + c172code + c12hour) 37 | #' plot_kfold_cv(mtcars, mpg ~.) 38 | #' 39 | #' # for poisson models. need to fit a model and use 'fit'-argument 40 | #' fit <- glm(tot_sc_e ~ neg_c_7 + c172code, data = efc, family = poisson) 41 | #' plot_kfold_cv(efc, fit = fit) 42 | #' 43 | #' # and for negative binomial models 44 | #' fit <- MASS::glm.nb(tot_sc_e ~ neg_c_7 + c172code, data = efc) 45 | #' plot_kfold_cv(efc, fit = fit) 46 | #' 47 | #' @import ggplot2 48 | #' @export 49 | plot_kfold_cv <- function(data, formula, k = 5, fit) { 50 | # make sure that data is a data frame 51 | if (!is.data.frame(data)) data <- as.data.frame(data) 52 | 53 | # check if a formula was passed as argument... 54 | if (!missing(formula)) { 55 | # make sure we have a formula 56 | if (!inherits(formula, "formula")) formula <- stats::as.formula(formula) 57 | # reset fam 58 | fam <- NULL 59 | } else if (!missing(fit)) { 60 | # ... or a fitted model 61 | formula <- stats::formula(fit) 62 | 63 | # get model family for glm 64 | if (inherits(fit, "glm")) 65 | fam <- stats::family(fit) 66 | else 67 | fam <- NULL 68 | } else { 69 | stop("Either `formula` or `fit` must be supplied.", call. = FALSE) 70 | } 71 | 72 | # get name of response variable and get variable label, if 73 | # there is any... used for labelling plot axis 74 | resp <- formula[[2]] 75 | resp.name <- sjlabelled::get_label(data[[deparse(resp)]], def.value = deparse(resp)) 76 | 77 | # check if fit parameter was specified, and we have a model family 78 | if (!is.null(fam)) { 79 | # for poisson models, show deviance residuals 80 | if (fam$family == "poisson") { 81 | # create cross-validated test-training pairs, run poisson-model on each 82 | # pair, get deviance residuals and response value 83 | kfolds <- do.call(rbind, lapply(1:k, function(i) { 84 | out <- datawizard::data_partition(data, training_proportion = .8) 85 | data.frame(train = I(list(out[[1]])), test = I(list(out$test))) 86 | })) 87 | res <- kfolds %>% 88 | dplyr::mutate(model = purrr::map(.data$train, ~ stats::glm(formula, data = .x, family = stats::poisson(link = "log")))) %>% 89 | dplyr::mutate(residuals = purrr::map(.data$model, ~ stats::residuals(.x, "deviance"))) %>% 90 | dplyr::mutate(.response = purrr::map(.data$model, ~ insight::get_response(.x))) 91 | # for negative binomial models, show deviance residuals 92 | } else if (inherits(fit, "negbin")) { 93 | # create cross-validated test-training pairs, run poisson-model on each 94 | # pair, get deviance residuals and response value 95 | kfolds <- do.call(rbind, lapply(1:k, function(i) { 96 | out <- datawizard::data_partition(data, training_proportion = .8) 97 | data.frame(train = I(list(out[[1]])), test = I(list(out$test))) 98 | })) 99 | res <- kfolds %>% 100 | dplyr::mutate(model = purrr::map(.data$train, ~ MASS::glm.nb(formula, data = .))) %>% 101 | dplyr::mutate(residuals = purrr::map(.data$model, ~ stats::residuals(.x, "deviance"))) %>% 102 | dplyr::mutate(.response = purrr::map(.data$model, ~ insight::get_response(.x))) 103 | } 104 | 105 | # unnest residuals and response values 106 | res <- suppressWarnings(res %>% tidyr::unnest(residuals, .data$.response)) 107 | 108 | } else { 109 | # create cross-validated test-training pairs, run linear model on each 110 | # pair, get predicted values and quality measures for models fitted on the 111 | # train data 112 | kfolds <- do.call(rbind, lapply(1:k, function(i) { 113 | out <- datawizard::data_partition(data, training_proportion = .8) 114 | data.frame(train = I(list(out[[1]])), test = I(list(out$test))) 115 | })) 116 | res <- kfolds %>% 117 | dplyr::mutate(model = purrr::map(.data$train, ~ stats::lm(formula, data = .))) %>% 118 | dplyr::mutate(predicted = purrr::map2(.data$model, .data$test, function(.x, .y) { 119 | out <- data.frame(.fitted = stats::predict(.x, newdata = .y)) 120 | cbind(.y, out) 121 | })) %>% 122 | tidyr::unnest(cols = .data$predicted) 123 | 124 | # make sure that response vector has an identifiably name 125 | colnames(res)[which(colnames(res) == deparse(resp))] <- ".response" 126 | 127 | # compute residuals for each k-fold model 128 | res <- res %>% 129 | dplyr::mutate(residuals = .data$.response - .data$.fitted) 130 | } 131 | 132 | # plot response against residuals, to see where our model over- or 133 | # underestimates the outcome 134 | p <- ggplot(data = res, aes_string(x = ".response", y = "residuals")) + 135 | geom_hline(yintercept = 0) + 136 | geom_point() + 137 | stat_smooth(method = "loess") + 138 | theme_minimal() + 139 | labs(y = "Residuals", x = resp.name) 140 | 141 | # plot it 142 | p 143 | } 144 | -------------------------------------------------------------------------------- /R/plot_residuals.R: -------------------------------------------------------------------------------- 1 | #' @title Plot predicted values and their residuals 2 | #' @name plot_residuals 3 | #' 4 | #' @description This function plots observed and predicted values of the response 5 | #' of linear (mixed) models for each coefficient and highlights the 6 | #' observed values according to their distance (residuals) to the 7 | #' predicted values. This allows to investigate how well actual and 8 | #' predicted values of the outcome fit across the predictor variables. 9 | #' 10 | #' @param fit Fitted linear (mixed) regression model (including objects of class 11 | #' \code{\link[nlme]{gls}} or \code{plm}). 12 | #' @param show.lines Logical, if \code{TRUE}, a line connecting predicted and 13 | #' residual values is plotted. Set this argument to \code{FALSE}, if 14 | #' plot-building is too time consuming. 15 | #' @param show.resid Logical, if \code{TRUE}, residual values are plotted. 16 | #' @param show.pred Logical, if \code{TRUE}, predicted values are plotted. 17 | #' @param remove.estimates Numeric vector with indices (order equals to row index of \code{coef(fit)}) 18 | #' or character vector with coefficient names that indicate which estimates should be removed 19 | #' from the table output. The first estimate is the intercept, followed by the model predictors. 20 | #' \emph{The intercept cannot be removed from the table output!} \code{remove.estimates = c(2:4)} 21 | #' would remove the 2nd to the 4th estimate (1st to 3rd predictor after intercept) from the output. 22 | #' \code{remove.estimates = "est_name"} would remove the estimate \emph{est_name}. Default 23 | #' is \code{NULL}, i.e. all estimates are printed. 24 | #' 25 | #' @inheritParams plot_model 26 | #' @inheritParams plot_scatter 27 | #' @inheritParams plot_grpfrq 28 | #' 29 | #' @return A ggplot-object. 30 | #' 31 | #' @note The actual (observed) values have a coloured fill, while the predicted 32 | #' values have a solid outline without filling. 33 | #' 34 | #' @examples 35 | #' data(efc) 36 | #' # fit model 37 | #' fit <- lm(neg_c_7 ~ c12hour + e17age + e42dep, data = efc) 38 | #' 39 | #' # plot residuals for all independent variables 40 | #' plot_residuals(fit) 41 | #' 42 | #' # remove some independent variables from output 43 | #' plot_residuals(fit, remove.estimates = c("e17age", "e42dep")) 44 | #' 45 | #' @importFrom rlang .data 46 | #' @export 47 | plot_residuals <- function(fit, geom.size = 2, remove.estimates = NULL, show.lines = TRUE, 48 | show.resid = TRUE, show.pred = TRUE, show.ci = FALSE) { 49 | # show lines only when both residual and predicted 50 | # values are plotted - else, lines make no sense 51 | if (!show.pred || !show.resid) show.lines <- FALSE 52 | 53 | # Obtain predicted and residual values 54 | mydat <- insight::get_data(fit, verbose = FALSE) 55 | 56 | # check whether estimates should be removed from plot 57 | if (!is.null(remove.estimates)) { 58 | keep <- which(!colnames(mydat) %in% remove.estimates) 59 | } else { 60 | keep <- seq_len(ncol(mydat)) 61 | } 62 | mydat$predicted <- stats::predict(fit) 63 | mydat$residuals <- stats::residuals(fit) 64 | 65 | # get name of response, used in ggplot-aes 66 | rv <- insight::find_response(fit) 67 | 68 | # remove estimates, if required 69 | dummy <- mydat %>% dplyr::select(keep, .data$predicted, .data$residuals) 70 | 71 | # set default variable labels, used as column names, so labelled 72 | # data variable labels appear in facet grid header. 73 | sel <- 2:length(keep) 74 | var.labels <- sjlabelled::get_label(dummy, def.value = colnames(dummy)[sel])[sel] 75 | if (is.null(var.labels) || all(var.labels == "")) var.labels <- colnames(dummy)[sel] 76 | colnames(dummy)[sel] <- var.labels 77 | 78 | # melt data 79 | mydat <- suppressWarnings(dummy %>% 80 | tidyr::gather(key = "grp", value = "x", -1, -.data$predicted, -.data$residuals)) 81 | 82 | colnames(mydat)[1] <- ".response" 83 | 84 | # melt data, build basic plot 85 | res.plot <- ggplot(mydat, aes(x = .data$x, y = .data$.response)) + 86 | stat_smooth(method = "lm", se = show.ci, colour = "grey70") 87 | 88 | if (show.lines) res.plot <- res.plot + 89 | geom_segment(aes(xend = .data$x, yend = .data$predicted), alpha = .3) 90 | 91 | if (show.resid) res.plot <- res.plot + 92 | geom_point(aes(fill = .data$residuals), size = geom.size, shape = 21, colour = "grey50") 93 | 94 | if (show.pred) res.plot <- res.plot + 95 | geom_point(aes(y = .data$predicted), shape = 1, size = geom.size) 96 | 97 | # residual plot 98 | res.plot <- res.plot + 99 | facet_grid(~grp, scales = "free") + 100 | scale_fill_gradient2(low = "#003399", mid = "white", high = "#993300") + 101 | guides(color = "none", fill = "none") + 102 | labs(x = NULL, y = sjlabelled::get_label(mydat[[1]], def.value = rv)) 103 | 104 | res.plot 105 | } 106 | -------------------------------------------------------------------------------- /R/plot_type_eff.R: -------------------------------------------------------------------------------- 1 | #' @importFrom ggeffects ggpredict ggeffect 2 | plot_type_eff <- function(type, 3 | model, 4 | terms, 5 | ci.lvl, 6 | pred.type, 7 | facets, 8 | show.data, 9 | jitter, 10 | geom.colors, 11 | axis.title, 12 | title, 13 | legend.title, 14 | axis.lim, 15 | case, 16 | show.legend, 17 | dot.size, 18 | line.size, 19 | ...) { 20 | 21 | if (missing(facets) || is.null(facets)) facets <- FALSE 22 | 23 | pred.type <- switch(pred.type, 24 | fe = "fixed", 25 | re = "random", 26 | pred.type 27 | ) 28 | 29 | if (type == "pred") { 30 | dat <- ggeffects::ggpredict( 31 | model = model, 32 | terms = terms, 33 | ci_level = ci.lvl, 34 | type = pred.type, 35 | ... 36 | ) 37 | } else if (type == "emm") { 38 | dat <- ggeffects::ggemmeans( 39 | model = model, 40 | terms = terms, 41 | ci_level = ci.lvl, 42 | type = pred.type, 43 | ... 44 | ) 45 | } else { 46 | dat <- ggeffects::ggeffect( 47 | model = model, 48 | terms = terms, 49 | ci_level = ci.lvl, 50 | ... 51 | ) 52 | } 53 | 54 | 55 | if (is.null(dat)) return(NULL) 56 | 57 | # evaluate dots-arguments 58 | alpha <- .15 59 | dodge <- .1 60 | dot.alpha <- .5 61 | log.y <- FALSE 62 | 63 | # save number of terms, needed later 64 | n.terms <- length(insight::find_predictors(model, component = "conditional", flatten = TRUE)) 65 | 66 | add.args <- lapply(match.call(expand.dots = F)$`...`, function(x) x) 67 | if ("alpha" %in% names(add.args)) alpha <- eval(add.args[["alpha"]]) 68 | if ("dodge" %in% names(add.args)) dodge <- eval(add.args[["dodge"]]) 69 | if ("dot.alpha" %in% names(add.args)) dot.alpha <- eval(add.args[["dot.alpha"]]) 70 | if ("log.y" %in% names(add.args)) log.y <- eval(add.args[["log.y"]]) 71 | 72 | 73 | # select color palette 74 | if (geom.colors[1] != "bw") { 75 | if (is.null(terms)) { 76 | if (facets) { 77 | geom.colors <- "bw" 78 | .ngrp <- n.terms 79 | } else { 80 | .ngrp <- 1 81 | } 82 | } else { 83 | .ngrp <- dplyr::n_distinct(dat$group) 84 | } 85 | geom.colors <- col_check2(geom.colors, .ngrp) 86 | } 87 | 88 | 89 | p <- graphics::plot( 90 | dat, 91 | show_ci = !is.na(ci.lvl), 92 | facets = facets, 93 | show_data = show.data, 94 | colors = geom.colors, 95 | use_theme = FALSE, 96 | jitter = jitter, 97 | case = case, 98 | show_legend = show.legend, 99 | dot_alpha = dot.alpha, 100 | alpha = alpha, 101 | dodge = dodge, 102 | log_y = log.y, 103 | dot_size = dot.size, 104 | line_size = line.size 105 | ) 106 | 107 | 108 | # set axis and plot titles 109 | if (!is.null(axis.title) && !is.null(terms)) { 110 | if (length(axis.title) > 1) { 111 | p <- p + labs(x = axis.title[1], y = axis.title[2]) 112 | } else { 113 | p <- p + labs(y = axis.title) 114 | } 115 | } else if (!is.null(axis.title) && is.null(terms)) { 116 | if (length(axis.title) > 1) { 117 | p <- purrr::map(p, ~ .x + labs(x = axis.title[1], y = axis.title[2])) 118 | } else { 119 | p <- purrr::map(p, ~ .x + labs(y = axis.title)) 120 | } 121 | } 122 | 123 | # set axis and plot titles 124 | if (!is.null(title) && !is.null(terms)) 125 | p <- p + ggtitle(title) 126 | else if (!is.null(title) && is.null(terms)) 127 | p <- purrr::map(p, ~ .x + ggtitle(title)) 128 | 129 | # set axis and plot titles 130 | if (!is.null(legend.title)) { 131 | if (geom.colors[1] == "bw") { 132 | p <- p + 133 | labs(linetype = legend.title) + 134 | guides(colour = "none") 135 | } else { 136 | p <- p + labs(colour = legend.title) 137 | } 138 | } 139 | 140 | 141 | # set axis limits 142 | if (!is.null(axis.lim)) { 143 | if (is.list(axis.lim)) 144 | p <- p + xlim(axis.lim[[1]]) + ylim(axis.lim[[2]]) 145 | else 146 | p <- p + ylim(axis.lim) 147 | } 148 | 149 | 150 | p 151 | } 152 | -------------------------------------------------------------------------------- /R/plot_type_est.R: -------------------------------------------------------------------------------- 1 | #' @importFrom sjmisc add_variables 2 | plot_type_est <- function(type, 3 | ci.lvl, 4 | se, 5 | tf, 6 | model, 7 | terms, 8 | group.terms, 9 | rm.terms, 10 | sort.est, 11 | title, 12 | axis.title, 13 | axis.labels, 14 | axis.lim, 15 | grid.breaks, 16 | show.intercept, 17 | show.values, 18 | show.p, 19 | value.offset, 20 | digits, 21 | geom.colors, 22 | geom.size, 23 | line.size, 24 | order.terms, 25 | vline.color, 26 | value.size, 27 | bpe, 28 | bpe.style, 29 | bpe.color, 30 | facets, 31 | show.zeroinf, 32 | p.threshold, 33 | p.val, 34 | vcov.fun, 35 | vcov.type, 36 | vcov.args, 37 | ci.style, 38 | p_adjust, 39 | std.response, 40 | ...) { 41 | 42 | if (missing(facets)) facets <- TRUE 43 | 44 | # get tidy output of summary ---- 45 | 46 | if (type == "std" || type == "std2") { 47 | std_method <- switch(type, "std" = "refit", "std2" = "2sd", "refit") 48 | } else { 49 | std_method <- FALSE 50 | } 51 | 52 | dat <- 53 | tidy_model( 54 | model = model, 55 | ci.lvl = ci.lvl, 56 | tf = tf, 57 | type = type, 58 | bpe = bpe, 59 | robust = list(vcov.fun = vcov.fun, vcov.type = vcov.type, vcov.args = vcov.args), 60 | facets = facets, 61 | show.zeroinf = show.zeroinf, 62 | p.val = p.val, 63 | standardize = std_method, 64 | bootstrap = FALSE, 65 | iterations = 1000, 66 | seed = NULL, 67 | p_adjust = p_adjust, 68 | std.response = std.response, 69 | ... 70 | ) 71 | 72 | # fix brms coefficient names 73 | 74 | if (inherits(model, "brmsfit")) { 75 | dat$term <- gsub("^b_", "", dat$term) 76 | } 77 | 78 | 79 | # check if facet groups need to be replaced with title 80 | 81 | if (length(title) > 1) { 82 | 83 | tnames <- names(title) 84 | 85 | if (obj_has_name(dat, "facet") && !is.null(tnames)) { 86 | if (all(tnames %in% dat$facet)) { 87 | for (i in tnames) { 88 | dat$facet[which(dat$facet == i)] <- title[i] 89 | } 90 | title <- "" 91 | } 92 | } 93 | 94 | if (obj_has_name(dat, "response.level") && !is.null(tnames)) { 95 | if (all(tnames %in% dat$response.level)) { 96 | for (i in tnames) { 97 | dat$response.level[which(dat$response.level == i)] <- title[i] 98 | } 99 | title <- "" 100 | } 101 | } 102 | 103 | } 104 | 105 | 106 | # se needs to be logical from here on 107 | if (!is.null(se) && !is.logical(se)) se <- TRUE 108 | 109 | # for stan-models, we can define the style of the Bayesian point estimate, 110 | # which may be a line or a dot. 111 | 112 | if (missing(bpe.style) || is.null(bpe.style)) bpe.style <- "line" 113 | if (missing(value.size) || is.null(value.size)) value.size <- 4 114 | 115 | 116 | plot_model_estimates( 117 | model = model, 118 | dat = dat, 119 | tf = tf, 120 | se = se, 121 | terms = terms, 122 | group.terms = group.terms, 123 | rm.terms = rm.terms, 124 | sort.est = sort.est, 125 | title = title, 126 | axis.title = axis.title, 127 | axis.labels = axis.labels, 128 | axis.lim = axis.lim, 129 | grid.breaks = grid.breaks, 130 | show.intercept = show.intercept, 131 | show.values = show.values, 132 | show.p = show.p, 133 | value.offset = value.offset, 134 | digits = digits, 135 | geom.colors = geom.colors, 136 | geom.size = geom.size, 137 | line.size = line.size, 138 | bpe.style = bpe.style, 139 | bpe.color = bpe.color, 140 | term.order = order.terms, 141 | vline.color = vline.color, 142 | value.size = value.size, 143 | facets = facets, 144 | p.threshold = p.threshold, 145 | ci.style = ci.style, 146 | ... 147 | ) 148 | } 149 | -------------------------------------------------------------------------------- /R/plot_type_slope.R: -------------------------------------------------------------------------------- 1 | plot_type_slope <- function(model, 2 | terms, 3 | rm.terms, 4 | ci.lvl, 5 | colors, 6 | show.data, 7 | jitter, 8 | facets, 9 | axis.title, 10 | case, 11 | useResiduals, 12 | ...) { 13 | 14 | alpha <- .2 15 | show.loess <- TRUE 16 | 17 | if (missing(facets)) facets <- TRUE 18 | 19 | # additional arguments? 20 | 21 | add.args <- lapply(match.call(expand.dots = F)$`...`, function(x) x) 22 | if ("alpha" %in% names(add.args)) alpha <- eval(add.args[["alpha"]]) 23 | if ("show.loess" %in% names(add.args)) show.loess <- eval(add.args[["show.loess"]]) 24 | 25 | 26 | # set color defaults 27 | 28 | colors <- col_check2(colors, if (isTRUE(show.loess)) 3 else 2) 29 | 30 | if (isTRUE(show.loess)) { 31 | lineColor <- colors[1] 32 | loessLineColor <- colors[2] 33 | pointColor <- colors[3] 34 | } else { 35 | lineColor <- colors[1] 36 | pointColor <- colors[2] 37 | } 38 | 39 | 40 | 41 | # retrieve amount of predictor variables and 42 | # retrieve column names of dataset so we can identify in which 43 | # column the data for each predictor is. 44 | 45 | model_data <- insight::get_data(model, verbose = FALSE) 46 | depvar.label <- sjlabelled::get_label(model_data[[1]], def.value = insight::find_response(model), case = case) 47 | predvars <- insight::find_predictors(model, component = "conditional", flatten = TRUE) 48 | 49 | 50 | # tell user that interaction terms are not supported by this method 51 | 52 | if (sjmisc::str_contains(deparse(stats::formula(model)), c(":", "*"), logic = "or")) { 53 | warning("Interaction terms are not supported by this plot type. Output for interaction terms may be inappropriate.", call. = F) 54 | } 55 | 56 | 57 | # remove estimates? 58 | 59 | if (!is.null(rm.terms)) { 60 | remcols <- match(rm.terms, predvars) 61 | 62 | if (!sjmisc::is_empty(remcols)) 63 | predvars <- predvars[-remcols] 64 | } 65 | 66 | 67 | # select specific setimates? 68 | 69 | if (!is.null(terms)) { 70 | remcols <- match(terms, predvars) 71 | 72 | if (!sjmisc::is_empty(remcols)) 73 | predvars <- predvars[remcols] 74 | } 75 | 76 | 77 | # retrieve name of dependent variable 78 | 79 | response <- ifelse(isTRUE(useResiduals), "residuals", depvar.label) 80 | 81 | # iterate all predictors 82 | 83 | mydat <- suppressWarnings(purrr::map_df(predvars, function(p_v) { 84 | 85 | # make sure we have the variable in our data. for mixed 86 | # models, we might have some random effects which were not 87 | # in the model frame 88 | 89 | if (obj_has_name(model_data, p_v)) { 90 | 91 | if (useResiduals) { 92 | data_frame( 93 | x = sjlabelled::as_numeric(model_data[[p_v]]), 94 | y = stats::residuals(model), 95 | group = sjlabelled::get_label(model_data[[p_v]], def.value = p_v, case = case) 96 | ) 97 | } else { 98 | data_frame( 99 | x = sjlabelled::as_numeric(model_data[[p_v]]), 100 | y = insight::get_response(model), 101 | group = sjlabelled::get_label(model_data[[p_v]], def.value = p_v, case = case) 102 | ) 103 | } 104 | 105 | } 106 | })) 107 | 108 | 109 | # facets, all in one plot 110 | 111 | if (facets) { 112 | 113 | p <- ggplot(mydat, aes(x = .data$x, y = .data$y)) + 114 | stat_smooth( 115 | method = "lm", se = !is.na(ci.lvl), colour = lineColor, 116 | fill = lineColor, alpha = alpha, level = ci.lvl 117 | ) 118 | 119 | if (isTRUE(show.loess)) 120 | p <- p + stat_smooth(method = "loess", colour = loessLineColor, se = FALSE) 121 | 122 | 123 | # plot raw data if requested 124 | 125 | if (show.data) { 126 | if (!is.null(jitter)) 127 | p <- p + geom_jitter(alpha = .2, colour = pointColor, shape = 16, width = jitter) 128 | else 129 | p <- p + geom_point(alpha = .2, colour = pointColor, shape = 16) 130 | } 131 | 132 | 133 | 134 | p <- p + facet_wrap(~group, scales = "free") 135 | 136 | 137 | # set plot labs 138 | p <- p + labs(x = NULL, y = response) 139 | 140 | } else { 141 | 142 | p <- list() 143 | 144 | for (p_v in unique(mydat$group)) { 145 | 146 | dat <- dplyr::filter(mydat, .data$group == !! p_v) 147 | 148 | pl <- ggplot(dat, aes(x = .data$x, y = .data$y)) + 149 | stat_smooth( 150 | method = "lm", se = !is.na(ci.lvl), colour = lineColor, 151 | fill = lineColor, alpha = alpha, level = ci.lvl 152 | ) 153 | 154 | if (isTRUE(show.loess)) 155 | pl <- pl + stat_smooth(method = "loess", colour = loessLineColor, se = FALSE) 156 | 157 | 158 | # plot raw data if requested 159 | 160 | if (show.data) 161 | pl <- pl + geom_point(alpha = .2, colour = pointColor, shape = 16) 162 | 163 | 164 | # set plot labs. check if we have custom axis titles 165 | 166 | if (!is.null(axis.title)) { 167 | 168 | if (is.list(axis.title)) { 169 | xt <- axis.title[[length(p) + 1]][1] 170 | yt <- axis.title[[length(p) + 1]][2] 171 | } else { 172 | xt <- axis.title[1] 173 | yt <- axis.title[2] 174 | } 175 | 176 | } else { 177 | xt <- p_v 178 | yt <- response 179 | } 180 | 181 | pl <- pl + 182 | labs(x = xt, y = yt) 183 | 184 | 185 | # add plot object to list 186 | p[[length(p) + 1]] <- pl 187 | } 188 | } 189 | 190 | p 191 | } 192 | -------------------------------------------------------------------------------- /R/save_plot.R: -------------------------------------------------------------------------------- 1 | #' @title Save ggplot-figure for print publication 2 | #' @name save_plot 3 | #' 4 | #' @description Convenient function to save the last ggplot-figure in 5 | #' high quality for publication. 6 | #' 7 | #' @param filename Name of the output file; filename must end with one 8 | #' of the following accepted file types: ".png", ".jpg", ".svg" or ".tif". 9 | #' @param fig The plot that should be saved. By default, the last plot is saved. 10 | #' @param width Width of the figure, in centimetres. 11 | #' @param height Height of the figure, in centimetres. 12 | #' @param dpi Resolution in dpi (dots per inch). Ignored for vector formats, such as ".svg". 13 | #' @param theme The default theme to use when saving the plot. 14 | #' @param label.color Color value for labels (axis, plot, etc.). 15 | #' @param label.size Fontsize of value labels inside plot area. 16 | #' @param axis.textsize Fontsize of axis labels. 17 | #' @param axis.titlesize Fontsize of axis titles. 18 | #' @param legend.textsize Fontsize of legend labels. 19 | #' @param legend.titlesize Fontsize of legend title. 20 | #' @param legend.itemsize Size of legend's item (legend key), in centimetres. 21 | #' 22 | #' @note This is a convenient function with some default settings that should 23 | #' come close to most of the needs for fontsize and scaling in figures 24 | #' when saving them for printing or publishing. It uses cairographics 25 | #' anti-aliasing (see \code{\link[grDevices]{png}}). 26 | #' \cr \cr 27 | #' For adjusting plot appearance, see also \code{\link{sjPlot-themes}}. 28 | #' 29 | #' @import ggplot2 30 | #' @importFrom grDevices png jpeg tiff dev.off cm svg 31 | #' @export 32 | save_plot <- function(filename, 33 | fig = last_plot(), 34 | width = 12, 35 | height = 9, 36 | dpi = 300, 37 | theme = theme_get(), 38 | label.color = "black", 39 | label.size = 2.4, 40 | axis.textsize = .8, 41 | axis.titlesize = .75, 42 | legend.textsize = .6, 43 | legend.titlesize = .65, 44 | legend.itemsize = .5) { 45 | # get file extension 46 | ext <- tolower(substring(filename, 47 | regexpr("\\.[^\\.]*$", filename) + 1, 48 | nchar(filename))) 49 | 50 | # valid file ytpe? 51 | if (!ext %in% c("png", "jpg", "tif", "svg")) 52 | stop("filetype must be one of `.png`, `.jpg`, '.svg' or `.tif`.", call. = F) 53 | 54 | # set printable theme, adjust font sizes. 55 | # this is the most critical point... 56 | 57 | set_theme( 58 | base = theme, 59 | geom.label.color = label.color, 60 | axis.title.color = label.color, 61 | axis.textcolor = label.color, 62 | legend.title.color = label.color, 63 | legend.color = label.color, 64 | geom.label.size = label.size, 65 | axis.textsize = axis.textsize, 66 | axis.title.size = axis.titlesize, 67 | legend.size = legend.textsize, 68 | legend.title.size = legend.titlesize, 69 | legend.item.size = legend.itemsize 70 | ) 71 | 72 | 73 | # prapare save 74 | 75 | if (ext == "png") 76 | grDevices::png( 77 | filename = filename, 78 | width = width, 79 | height = height, 80 | units = "cm", 81 | res = dpi, 82 | type = "cairo" 83 | ) 84 | else if (ext == "jpg") 85 | grDevices::jpeg( 86 | filename = filename, 87 | width = width, 88 | height = height, 89 | units = "cm", 90 | res = dpi, 91 | type = "cairo" 92 | ) 93 | else if (ext == "tif") 94 | grDevices::tiff( 95 | filename = filename, 96 | width = width, 97 | height = height, 98 | units = "cm", 99 | res = dpi, 100 | type = "cairo" 101 | ) 102 | else if (ext == 'svg') 103 | grDevices::svg( 104 | filename = filename, 105 | width = width / grDevices::cm(1), 106 | height = height / grDevices::cm(1) 107 | ) 108 | 109 | # print plot to device 110 | graphics::plot(fig) 111 | 112 | # close device 113 | grDevices::dev.off() 114 | } 115 | -------------------------------------------------------------------------------- /R/select_helpers.R: -------------------------------------------------------------------------------- 1 | string_starts_with <- function(pattern, x) { 2 | pattern <- paste0("^\\Q", pattern, "\\E") 3 | grep(pattern, x, perl = TRUE) 4 | } 5 | 6 | string_contains <- function(pattern, x) { 7 | pattern <- paste0("\\Q", pattern, "\\E") 8 | grep(pattern, x, perl = TRUE) 9 | } 10 | 11 | string_ends_with <- function(pattern, x) { 12 | pattern <- paste0("\\Q", pattern, "\\E$") 13 | grep(pattern, x, perl = TRUE) 14 | } 15 | 16 | #' @importFrom purrr map 17 | string_one_of <- function(pattern, x) { 18 | m <- unlist(purrr::map(pattern, ~ grep(., x, fixed = TRUE, useBytes = TRUE))) 19 | x[m] 20 | } 21 | 22 | rownames_as_column <- function(x, var = "rowname", rownames = NULL) { 23 | if (is.null(rownames)) { 24 | rn <- rownames(x) 25 | } else { 26 | rn <- rownames 27 | } 28 | rn <- data.frame(rn = rn, stringsAsFactors = FALSE) 29 | x <- cbind(rn, x) 30 | colnames(x)[1] <- var 31 | rownames(x) <- NULL 32 | x 33 | } 34 | 35 | obj_has_name <- function(x, name) { 36 | name %in% names(x) 37 | } 38 | 39 | obj_has_rownames <- function(x) { 40 | !identical(as.character(1:nrow(x)), rownames(x)) 41 | } 42 | 43 | 44 | 45 | #' @importFrom stats reshape 46 | #' @keywords internal 47 | .gather <- function(x, names_to = "key", values_to = "value", columns = colnames(x)) { 48 | if (is.numeric(columns)) columns <- colnames(x)[columns] 49 | dat <- stats::reshape( 50 | x, 51 | idvar = "id", 52 | ids = row.names(x), 53 | times = columns, 54 | timevar = names_to, 55 | v.names = values_to, 56 | varying = list(columns), 57 | direction = "long" 58 | ) 59 | 60 | if (is.factor(dat[[values_to]])) 61 | dat[[values_to]] <- as.character(dat[[values_to]]) 62 | 63 | dat[, 1:(ncol(dat) - 1), drop = FALSE] 64 | } 65 | -------------------------------------------------------------------------------- /R/sjPlotPearsonsChi2Test.R: -------------------------------------------------------------------------------- 1 | #' @title Plot Pearson's Chi2-Test of multiple contingency tables 2 | #' @name sjp.chi2 3 | #' 4 | #' @description Plot p-values of Pearson's Chi2-tests for multiple contingency tables as ellipses or tiles. 5 | #' Requires a data frame with dichotomous (dummy) variables. 6 | #' Calculation of Chi2-matrix taken from 7 | #' \href{https://talesofr.wordpress.com/2013/05/05/ridiculously-photogenic-factors-heatmap-with-p-values/}{Tales of R}. 8 | #' 9 | #' @param df A data frame with (dichotomous) factor variables. 10 | #' 11 | #' @return A ggplot-object. 12 | #' 13 | #' @inheritParams plot_grpfrq 14 | #' 15 | #' @examples 16 | #' # create data frame with 5 dichotomous (dummy) variables 17 | #' mydf <- data.frame(as.factor(sample(1:2, 100, replace=TRUE)), 18 | #' as.factor(sample(1:2, 100, replace=TRUE)), 19 | #' as.factor(sample(1:2, 100, replace=TRUE)), 20 | #' as.factor(sample(1:2, 100, replace=TRUE)), 21 | #' as.factor(sample(1:2, 100, replace=TRUE))) 22 | #' # create variable labels 23 | #' items <- list(c("Item 1", "Item 2", "Item 3", "Item 4", "Item 5")) 24 | #' 25 | #' # plot Chi2-contingency-table 26 | #' sjp.chi2(mydf, axis.labels = items) 27 | #' 28 | #' @import ggplot2 29 | #' @importFrom grDevices rgb 30 | #' @importFrom dplyr bind_rows 31 | #' @export 32 | sjp.chi2 <- function(df, 33 | title = "Pearson's Chi2-Test of Independence", 34 | axis.labels = NULL, 35 | wrap.title = 50, 36 | wrap.labels = 20, 37 | show.legend = FALSE, 38 | legend.title = NULL) { 39 | # -------------------------------------------------------- 40 | # try to automatically set labels is not passed as parameter 41 | # -------------------------------------------------------- 42 | if (is.null(axis.labels)) { 43 | axis.labels <- sjlabelled::get_label(df, def.value = colnames(df)) 44 | } 45 | # ---------------------------------------------------------------- 46 | # Calculation of Chi2-matrix taken from following blog-posting: 47 | # http://talesofr.wordpress.com/2013/05/05/ridiculously-photogenic-factors-heatmap-with-p-values/ 48 | # ---------------------------------------------------------------- 49 | combos <- expand.grid(rep(list(seq_len(ncol(df))), 2)) # combinations with repetitions 50 | combos <- as.matrix(combos) 51 | combos <- t(combos) # transpose matrix 52 | # ---------------------------------------------------------------- 53 | # when 2 variables are *not* significant, they are independent 54 | # ---------------------------------------------------------------- 55 | m <- data.frame() 56 | for (i in seq_len(ncol(combos))) { 57 | test <- chisq.test(df[, combos[1, i]], df[, combos[2, i]]) 58 | out <- data.frame(Row = colnames(df)[combos[1, i]], 59 | Column = colnames(df)[combos[2, i]], 60 | Chi.Square = round(test$statistic, 4), 61 | df = test$parameter, 62 | p.value = round(test$p.value, 4), 63 | stringsAsFactors = FALSE) 64 | m <- suppressWarnings(dplyr::bind_rows(m, out)) 65 | } 66 | # ---------------------------- 67 | # check if user defined labels have been supplied 68 | # if not, use variable names from data frame 69 | # ---------------------------- 70 | if (is.null(axis.labels)) axis.labels <- row.names(m) 71 | # -------------------------------------------------------- 72 | # unlist labels 73 | # -------------------------------------------------------- 74 | if (!is.null(axis.labels) && is.list(axis.labels)) { 75 | axis.labels <- unlistlabels(axis.labels) 76 | } 77 | # ---------------------------- 78 | # Prepare length of title and labels 79 | # ---------------------------- 80 | # check length of diagram title and split longer string at into new lines 81 | if (!is.null(title)) title <- sjmisc::word_wrap(title, wrap.title) 82 | # check length of x-axis-labels and split longer strings at into new lines 83 | if (!is.null(axis.labels)) axis.labels <- sjmisc::word_wrap(axis.labels, wrap.labels) 84 | # -------------------------------------------------------- 85 | # start with base plot object here 86 | # -------------------------------------------------------- 87 | chiPlot <- ggplot(data = m, aes_string(x = "Row", y = "Column", fill = "p.value", label = "p.value")) + 88 | geom_tile() + 89 | scale_x_discrete(labels = axis.labels) + 90 | scale_y_discrete(labels = axis.labels) + 91 | scale_fill_gradient2(low = grDevices::rgb(128, 205, 193, maxColorValue = 255), 92 | mid = "white", 93 | high = grDevices::rgb(5, 113, 176, maxColorValue = 255), 94 | midpoint = 0.05) + 95 | geom_text(label = sprintf("%.3f", m$p.value)) + 96 | labs(title = title, 97 | x = NULL, 98 | y = NULL, 99 | fill = legend.title) 100 | # --------------------------------------------------------- 101 | # hide legend? 102 | # --------------------------------------------------------- 103 | if (!show.legend) chiPlot <- chiPlot + guides(fill = "none") 104 | 105 | chiPlot 106 | } 107 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | .onAttach <- function(libname, pkgname) { 2 | if (stats::runif(1) > .8) { 3 | packageStartupMessage("Learn more about sjPlot with 'browseVignettes(\"sjPlot\")'.") 4 | } else if (stats::runif(1) > .8) { 5 | packageStartupMessage("Install package \"strengejacke\" from GitHub (`devtools::install_github(\"strengejacke/strengejacke\")`) to load all sj-packages at once!") 6 | } else if (stats::runif(1) > .8) { 7 | packageStartupMessage("#refugeeswelcome") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sjPlot - Data Visualization for Statistics in Social Science 2 | 3 | [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/sjPlot)](https://cran.r-project.org/package=sjPlot) 4 | 5 | Collection of plotting and table output functions for data visualization. Results of various statistical analyses (that are commonly used in social sciences) can be visualized using this package, including simple and cross tabulated frequencies, histograms, box plots, (generalized) linear models, mixed effects models, PCA and correlation matrices, cluster analyses, scatter plots, Likert scales, effects plots of interaction terms in regression models, constructing index or score variables and much more. 6 | 7 | ## Installation 8 | 9 | ### Latest development build 10 | 11 | To install the latest development snapshot (see latest changes below), type the following commands into the R console: 12 | 13 | ```r 14 | library(devtools) 15 | devtools::install_github("strengejacke/sjPlot") 16 | ``` 17 | 18 | ### Official, stable release 19 | 20 | To install the latest stable release from CRAN, type the following command into the R console: 21 | 22 | ```r 23 | install.packages("sjPlot") 24 | ``` 25 | 26 | ## Documentation and examples 27 | 28 | Please visit [https://strengejacke.github.io/sjPlot/](https://strengejacke.github.io/sjPlot/) for documentation and vignettes. 29 | 30 | ## Citation 31 | 32 | In case you want / have to cite my package, please use `citation('sjPlot')` for citation information. Since core functionality of package depends on the [ggplot-package](https://cran.r-project.org/package=ggplot2), consider citing this package as well. 33 | 34 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1308157.svg)](https://doi.org/10.5281/zenodo.1308157) 35 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://strengejacke.github.io/sjPlot/ 2 | 3 | template: 4 | bootstrap: 5 5 | bslib: 6 | base_font: {google: "Roboto"} 7 | heading_font: {google: "Roboto Slab"} 8 | code_font: {google: "JetBrains Mono"} 9 | 10 | authors: 11 | Daniel Lüdecke: 12 | href: https://github.com/strengejacke 13 | 14 | development: 15 | #mode: auto 16 | version_label: default 17 | version_tooltip: "Version" 18 | 19 | reference: 20 | - title: "Package Description" 21 | contents: 22 | - sjPlot-package 23 | 24 | - title: "Plotting Regression Models" 25 | contents: 26 | - plot_model 27 | - plot_models 28 | 29 | - title: "Regression Model Tables" 30 | contents: 31 | - tab_model 32 | 33 | - title: "Plotting Regression Model Diagnostics" 34 | contents: 35 | - plot_kfold_cv 36 | - plot_model 37 | - plot_residuals 38 | - sjp.poly 39 | 40 | - title: "Plotting Descriptive Statistics" 41 | contents: 42 | - plot_frq 43 | - plot_gpt 44 | - plot_likert 45 | - plot_scatter 46 | - plot_stackfrq 47 | - plot_grpfrq 48 | - plot_xtab 49 | - sjp.chi2 50 | - sjp.aov1 51 | - sjp.corr 52 | - sjplot 53 | 54 | - title: "Descriptive Statistics Tables" 55 | contents: 56 | - tab_stackfrq 57 | - tab_xtab 58 | - tab_corr 59 | 60 | - title: "Generate Tables from Data Frames, Codebooks" 61 | contents: 62 | - tab_df 63 | - view_df 64 | 65 | - title: "Variable/Feature Reduction" 66 | contents: 67 | - tab_fa 68 | - tab_pca 69 | - tab_itemscale 70 | 71 | - title: "Plot Customization" 72 | contents: 73 | - set_theme 74 | - theme_sjplot 75 | 76 | - title: "Plot Distributions" 77 | contents: 78 | - dist_chisq 79 | - dist_f 80 | - dist_norm 81 | - dist_t 82 | 83 | - title: "Utility Functions" 84 | contents: 85 | - plot_grid 86 | - save_plot 87 | 88 | - title: "Example Data" 89 | contents: 90 | - efc 91 | - save_plot 92 | 93 | navbar: 94 | type: default 95 | left: 96 | - icon: fa-home fa-lg 97 | href: index.html 98 | - text: News 99 | href: news/index.html 100 | - text: Reference 101 | href: reference/index.html 102 | - text: Regression Tables 103 | menu: 104 | - text: 'Classical Regression Models as HTML Table' 105 | href: articles/tab_model_estimates.html 106 | - text: 'Mixed Models as HTML Table' 107 | href: articles/tab_mixed.html 108 | - text: 'Bayesian Models as HTML Table' 109 | href: articles/tab_bayes.html 110 | - text: 'Robust Estimation of Standard Errors, Confidence Intervals and p-values' 111 | href: articles/tab_model_robust.html 112 | - text: Regression Plots 113 | menu: 114 | - text: 'Plotting Regression Coefficients' 115 | href: articles/plot_model_estimates.html 116 | - text: 'Plotting Marginal Effects' 117 | href: articles/plot_marginal_effects.html 118 | - text: 'Plotting Marginal Effects of Interactions' 119 | href: articles/plot_interactions.html 120 | - text: Plot and Table Customization 121 | menu: 122 | - text: 'Creating Black and White Figures' 123 | href: articles/blackwhitefigures.html 124 | - text: 'Customize Plot Appearance' 125 | href: articles/custplot.html 126 | - text: 'Customize Table Appearance' 127 | href: articles/table_css.html 128 | - text: Other Articles 129 | menu: 130 | - text: 'Item Analysis of a Scale or an Index' 131 | href: articles/sjtitemanalysis.html 132 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | This is a maintainance release, to meet changes in forthcoming downstream dependencies. -------------------------------------------------------------------------------- /data/efc.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strengejacke/sjPlot/374e4dfccda515e17828b91025cc404947302994/data/efc.RData -------------------------------------------------------------------------------- /devel.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageCheckArgs: --as-cran --no-vignettes 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | year <- sub("-.*", "", meta$Date) 2 | note <- sprintf("R package version %s", meta$Version) 3 | 4 | bibentry(bibtype="manual", 5 | title = "sjPlot: Data Visualization for Statistics in Social Science", 6 | author = person("Daniel", "Lüdecke"), 7 | year = year, 8 | note = note, 9 | url = "https://CRAN.R-project.org/package=sjPlot") 10 | -------------------------------------------------------------------------------- /man/dist_chisq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotDist.R 3 | \name{dist_chisq} 4 | \alias{dist_chisq} 5 | \title{Plot chi-squared distributions} 6 | \usage{ 7 | dist_chisq( 8 | chi2 = NULL, 9 | deg.f = NULL, 10 | p = NULL, 11 | xmax = NULL, 12 | geom.colors = NULL, 13 | geom.alpha = 0.7 14 | ) 15 | } 16 | \arguments{ 17 | \item{chi2}{Numeric, optional. If specified, a chi-squared distribution with \code{deg.f} degrees 18 | of freedom is plotted and a shaded area at \code{chi2} value position is plotted that 19 | indicates whether or not the specified value is significant or not. 20 | If both \code{chi2} and \code{p} are not specified, a distribution without shaded 21 | area is plotted.} 22 | 23 | \item{deg.f}{Numeric. The degrees of freedom for the chi-squared distribution. Needs to 24 | be specified.} 25 | 26 | \item{p}{Numeric, optional. If specified, a chi-squared distribution with \code{deg.f} degrees 27 | of freedom is plotted and a shaded area at the position where the specified p-level 28 | starts is plotted. If both \code{chi2} and \code{p} are not specified, a distribution 29 | without shaded area is plotted.} 30 | 31 | \item{xmax}{Numeric, optional. Specifies the maximum x-axis-value. If not specified, the x-axis 32 | ranges to a value where a p-level of 0.00001 is reached.} 33 | 34 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 35 | 36 | \item{geom.alpha}{Specifies the alpha-level of the shaded area. Default is 0.7, range between 0 to 1.} 37 | } 38 | \description{ 39 | This function plots a simple chi-squared distribution or a chi-squared distribution 40 | with shaded areas that indicate at which chi-squared value a significant p-level 41 | is reached. 42 | } 43 | \examples{ 44 | # a simple chi-squared distribution 45 | # for 6 degrees of freedom 46 | dist_chisq(deg.f = 6) 47 | 48 | # a chi-squared distribution for 6 degrees of freedom, 49 | # and a shaded area starting at chi-squared value of ten. 50 | # With a df of 6, a chi-squared value of 12.59 would be "significant", 51 | # thus the shaded area from 10 to 12.58 is filled as "non-significant", 52 | # while the area starting from chi-squared value 12.59 is filled as 53 | # "significant" 54 | dist_chisq(chi2 = 10, deg.f = 6) 55 | 56 | # a chi-squared distribution for 6 degrees of freedom, 57 | # and a shaded area starting at that chi-squared value, which has 58 | # a p-level of about 0.125 (which equals a chi-squared value of about 10). 59 | # With a df of 6, a chi-squared value of 12.59 would be "significant", 60 | # thus the shaded area from 10 to 12.58 (p-level 0.125 to p-level 0.05) 61 | # is filled as "non-significant", while the area starting from chi-squared 62 | # value 12.59 (p-level < 0.05) is filled as "significant". 63 | dist_chisq(p = 0.125, deg.f = 6) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /man/dist_f.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotDist.R 3 | \name{dist_f} 4 | \alias{dist_f} 5 | \title{Plot F distributions} 6 | \usage{ 7 | dist_f( 8 | f = NULL, 9 | deg.f1 = NULL, 10 | deg.f2 = NULL, 11 | p = NULL, 12 | xmax = NULL, 13 | geom.colors = NULL, 14 | geom.alpha = 0.7 15 | ) 16 | } 17 | \arguments{ 18 | \item{f}{Numeric, optional. If specified, an F distribution with \code{deg.f1} and \code{deg.f2} degrees 19 | of freedom is plotted and a shaded area at \code{f} value position is plotted that 20 | indicates whether or not the specified value is significant or not. 21 | If both \code{f} and \code{p} are not specified, a distribution without shaded 22 | area is plotted.} 23 | 24 | \item{deg.f1}{Numeric. The first degrees of freedom for the F distribution. Needs to 25 | be specified.} 26 | 27 | \item{deg.f2}{Numeric. The second degrees of freedom for the F distribution. Needs to 28 | be specified.} 29 | 30 | \item{p}{Numeric, optional. If specified, a F distribution with \code{deg.f1} and \code{deg.f2} degrees 31 | of freedom is plotted and a shaded area at the position where the specified p-level 32 | starts is plotted. If both \code{f} and \code{p} are not specified, a distribution 33 | without shaded area is plotted.} 34 | 35 | \item{xmax}{Numeric, optional. Specifies the maximum x-axis-value. If not specified, the x-axis 36 | ranges to a value where a p-level of 0.00001 is reached.} 37 | 38 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 39 | 40 | \item{geom.alpha}{Specifies the alpha-level of the shaded area. Default is 0.7, range between 0 to 1.} 41 | } 42 | \description{ 43 | This function plots a simple F distribution or an F distribution 44 | with shaded areas that indicate at which F value a significant p-level 45 | is reached. 46 | } 47 | \examples{ 48 | # a simple F distribution for 6 and 45 degrees of freedom 49 | dist_f(deg.f1 = 6, deg.f2 = 45) 50 | 51 | # F distribution for 6 and 45 degrees of freedom, 52 | # and a shaded area starting at F value of two. 53 | # F-values equal or greater than 2.31 are "significant" 54 | dist_f(f = 2, deg.f1 = 6, deg.f2 = 45) 55 | 56 | # F distribution for 6 and 45 degrees of freedom, 57 | # and a shaded area starting at a p-level of 0.2 58 | # (F-Value about 1.5). 59 | dist_f(p = 0.2, deg.f1 = 6, deg.f2 = 45) 60 | 61 | } 62 | -------------------------------------------------------------------------------- /man/dist_norm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotDist.R 3 | \name{dist_norm} 4 | \alias{dist_norm} 5 | \title{Plot normal distributions} 6 | \usage{ 7 | dist_norm( 8 | norm = NULL, 9 | mean = 0, 10 | sd = 1, 11 | p = NULL, 12 | xmax = NULL, 13 | geom.colors = NULL, 14 | geom.alpha = 0.7 15 | ) 16 | } 17 | \arguments{ 18 | \item{norm}{Numeric, optional. If specified, a normal distribution with \code{mean} and \code{sd} 19 | is plotted and a shaded area at \code{norm} value position is plotted that 20 | indicates whether or not the specified value is significant or not. 21 | If both \code{norm} and \code{p} are not specified, a distribution without shaded 22 | area is plotted.} 23 | 24 | \item{mean}{Numeric. Mean value for normal distribution. By default 0.} 25 | 26 | \item{sd}{Numeric. Standard deviation for normal distribution. By default 1.} 27 | 28 | \item{p}{Numeric, optional. If specified, a normal distribution with \code{mean} and \code{sd} 29 | is plotted and a shaded area at the position where the specified p-level 30 | starts is plotted. If both \code{norm} and \code{p} are not specified, a distribution 31 | without shaded area is plotted.} 32 | 33 | \item{xmax}{Numeric, optional. Specifies the maximum x-axis-value. If not specified, the x-axis 34 | ranges to a value where a p-level of 0.00001 is reached.} 35 | 36 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 37 | 38 | \item{geom.alpha}{Specifies the alpha-level of the shaded area. Default is 0.7, range between 0 to 1.} 39 | } 40 | \description{ 41 | This function plots a simple normal distribution or a normal distribution 42 | with shaded areas that indicate at which value a significant p-level 43 | is reached. 44 | } 45 | \examples{ 46 | # a simple normal distribution 47 | dist_norm() 48 | 49 | # a simple normal distribution with different mean and sd. 50 | # note that curve looks similar to above plot, but axis range 51 | # has changed. 52 | dist_norm(mean = 2, sd = 4) 53 | 54 | # a simple normal distribution 55 | dist_norm(norm = 1) 56 | 57 | # a simple normal distribution 58 | dist_norm(p = 0.2) 59 | 60 | } 61 | -------------------------------------------------------------------------------- /man/dist_t.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotDist.R 3 | \name{dist_t} 4 | \alias{dist_t} 5 | \title{Plot t-distributions} 6 | \usage{ 7 | dist_t( 8 | t = NULL, 9 | deg.f = NULL, 10 | p = NULL, 11 | xmax = NULL, 12 | geom.colors = NULL, 13 | geom.alpha = 0.7 14 | ) 15 | } 16 | \arguments{ 17 | \item{t}{Numeric, optional. If specified, a t-distribution with \code{deg.f} degrees 18 | of freedom is plotted and a shaded area at \code{t} value position is plotted that 19 | indicates whether or not the specified value is significant or not. 20 | If both \code{t} and \code{p} are not specified, a distribution without shaded 21 | area is plotted.} 22 | 23 | \item{deg.f}{Numeric. The degrees of freedom for the t-distribution. Needs to 24 | be specified.} 25 | 26 | \item{p}{Numeric, optional. If specified, a t-distribution with \code{deg.f} degrees 27 | of freedom is plotted and a shaded area at the position where the specified p-level 28 | starts is plotted. If both \code{t} and \code{p} are not specified, a distribution 29 | without shaded area is plotted.} 30 | 31 | \item{xmax}{Numeric, optional. Specifies the maximum x-axis-value. If not specified, the x-axis 32 | ranges to a value where a p-level of 0.00001 is reached.} 33 | 34 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 35 | 36 | \item{geom.alpha}{Specifies the alpha-level of the shaded area. Default is 0.7, range between 0 to 1.} 37 | } 38 | \description{ 39 | This function plots a simple t-distribution or a t-distribution 40 | with shaded areas that indicate at which t-value a significant p-level 41 | is reached. 42 | } 43 | \examples{ 44 | # a simple t-distribution 45 | # for 6 degrees of freedom 46 | dist_t(deg.f = 6) 47 | 48 | # a t-distribution for 6 degrees of freedom, 49 | # and a shaded area starting at t-value of one. 50 | # With a df of 6, a t-value of 1.94 would be "significant". 51 | dist_t(t = 1, deg.f = 6) 52 | 53 | # a t-distribution for 6 degrees of freedom, 54 | # and a shaded area starting at p-level of 0.4 55 | # (t-value of about 0.26). 56 | dist_t(p = 0.4, deg.f = 6) 57 | 58 | } 59 | -------------------------------------------------------------------------------- /man/efc.Rd: -------------------------------------------------------------------------------- 1 | \docType{data} 2 | \name{efc} 3 | \alias{efc} 4 | \title{Sample dataset from the EUROFAMCARE project} 5 | \description{ 6 | A SPSS sample data set, imported with the \code{\link[sjlabelled]{read_spss}} function. 7 | } 8 | \keyword{data} 9 | -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strengejacke/sjPlot/374e4dfccda515e17828b91025cc404947302994/man/figures/logo.png -------------------------------------------------------------------------------- /man/plot_gpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_gpt.R 3 | \name{plot_gpt} 4 | \alias{plot_gpt} 5 | \title{Plot grouped proportional tables} 6 | \usage{ 7 | plot_gpt( 8 | data, 9 | x, 10 | y, 11 | grp, 12 | colors = "metro", 13 | geom.size = 2.5, 14 | shape.fill.color = "#f0f0f0", 15 | shapes = c(15, 16, 17, 18, 21, 22, 23, 24, 25, 7, 8, 9, 10, 12), 16 | title = NULL, 17 | axis.labels = NULL, 18 | axis.titles = NULL, 19 | legend.title = NULL, 20 | legend.labels = NULL, 21 | wrap.title = 50, 22 | wrap.labels = 15, 23 | wrap.legend.title = 20, 24 | wrap.legend.labels = 20, 25 | axis.lim = NULL, 26 | grid.breaks = NULL, 27 | show.total = TRUE, 28 | annotate.total = TRUE, 29 | show.p = TRUE, 30 | show.n = TRUE 31 | ) 32 | } 33 | \arguments{ 34 | \item{data}{A data frame, or a grouped data frame.} 35 | 36 | \item{x}{Categorical variable, where the proportion of each category in 37 | \code{x} for the highest category of \code{y} will be printed 38 | along the x-axis.} 39 | 40 | \item{y}{Categorical or numeric variable. If not a binary variable, \code{y} 41 | will be recoded into a binary variable, dichtomized at the highest 42 | category and all remaining categories.} 43 | 44 | \item{grp}{Grouping variable, which will define the y-axis} 45 | 46 | \item{colors}{May be a character vector of color values in hex-format, valid 47 | color value names (see \code{demo("colors")}) or a name of a pre-defined 48 | color palette. Following options are valid for the \code{colors} argument: 49 | \itemize{ 50 | \item If not specified, a default color brewer palette will be used, which is suitable for the plot style. 51 | \item If \code{"gs"}, a greyscale will be used. 52 | \item If \code{"bw"}, and plot-type is a line-plot, the plot is black/white and uses different line types to distinguish groups (see \href{https://strengejacke.github.io/sjPlot/articles/blackwhitefigures.html}{this package-vignette}). 53 | \item If \code{colors} is any valid color brewer palette name, the related palette will be used. Use \code{RColorBrewer::display.brewer.all()} to view all available palette names. 54 | \item There are some pre-defined color palettes in this package, see \code{\link{sjPlot-themes}} for details. 55 | \item Else specify own color values or names as vector (e.g. \code{colors = "#00ff00"} or \code{colors = c("firebrick", "blue")}). 56 | }} 57 | 58 | \item{geom.size}{size resp. width of the geoms (bar width, line thickness or point size, 59 | depending on plot type and function). Note that bar and bin widths mostly 60 | need smaller values than dot sizes.} 61 | 62 | \item{shape.fill.color}{Optional color vector, fill-color for non-filled shapes} 63 | 64 | \item{shapes}{Numeric vector with shape styles, used to map the different 65 | categories of \code{x}.} 66 | 67 | \item{title}{Character vector, used as plot title. By default, 68 | \code{\link[sjlabelled]{response_labels}} is called to retrieve the label of 69 | the dependent variable, which will be used as title. Use \code{title = ""} 70 | to remove title.} 71 | 72 | \item{axis.labels}{character vector with labels used as axis labels. Optional 73 | argument, since in most cases, axis labels are set automatically.} 74 | 75 | \item{axis.titles}{character vector of length one or two, defining the title(s) 76 | for the x-axis and y-axis.} 77 | 78 | \item{legend.title}{Character vector, used as legend title for plots that 79 | have a legend.} 80 | 81 | \item{legend.labels}{character vector with labels for the guide/legend.} 82 | 83 | \item{wrap.title}{Numeric, determines how many chars of the plot title are 84 | displayed in one line and when a line break is inserted.} 85 | 86 | \item{wrap.labels}{numeric, determines how many chars of the value, variable or axis 87 | labels are displayed in one line and when a line break is inserted.} 88 | 89 | \item{wrap.legend.title}{numeric, determines how many chars of the legend's title 90 | are displayed in one line and when a line break is inserted.} 91 | 92 | \item{wrap.legend.labels}{numeric, determines how many chars of the legend labels are 93 | displayed in one line and when a line break is inserted.} 94 | 95 | \item{axis.lim}{Numeric vector of length 2, defining the range of the plot axis. 96 | Depending on plot type, may effect either x- or y-axis, or both. 97 | For multiple plot outputs (e.g., from \code{type = "eff"} or 98 | \code{type = "slope"} in \code{\link{plot_model}}), \code{axis.lim} may 99 | also be a list of vectors of length 2, defining axis limits for each 100 | plot (only if non-faceted).} 101 | 102 | \item{grid.breaks}{numeric; sets the distance between breaks for the axis, 103 | i.e. at every \code{grid.breaks}'th position a major grid is being printed.} 104 | 105 | \item{show.total}{Logical, if \code{TRUE}, a total summary line for all aggregated 106 | \code{grp} is added.} 107 | 108 | \item{annotate.total}{Logical, if \code{TRUE} and \code{show.total = TRUE}, 109 | the total-row in the figure will be highlighted with a slightly 110 | shaded background.} 111 | 112 | \item{show.p}{Logical, adds significance levels to values, or value and 113 | variable labels.} 114 | 115 | \item{show.n}{logical, if \code{TRUE}, adds total number of cases for each 116 | group or category to the labels.} 117 | } 118 | \value{ 119 | A ggplot-object. 120 | } 121 | \description{ 122 | Plot grouped proportional crosstables, where the proportion of 123 | each level of \code{x} for the highest category in \code{y} 124 | is plotted, for each subgroup of \code{grp}. 125 | } 126 | \details{ 127 | The p-values are based on \code{\link[stats]{chisq.test}} of \code{x} 128 | and \code{y} for each \code{grp}. 129 | } 130 | \examples{ 131 | if (requireNamespace("haven")) { 132 | data(efc) 133 | 134 | # the proportion of dependency levels in female 135 | # elderly, for each family carer's relationship 136 | # to elderly 137 | plot_gpt(efc, e42dep, e16sex, e15relat) 138 | 139 | # proportion of educational levels in highest 140 | # dependency category of elderly, for different 141 | # care levels 142 | plot_gpt(efc, c172code, e42dep, n4pstu) 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /man/plot_grid.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_grid.R 3 | \name{plot_grid} 4 | \alias{plot_grid} 5 | \title{Arrange list of plots as grid} 6 | \usage{ 7 | plot_grid(x, margin = c(1, 1, 1, 1), tags = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{A list of ggplot-objects. See 'Details'.} 11 | 12 | \item{margin}{A numeric vector of length 4, indicating the top, right, bottom 13 | and left margin for each plot, in centimetres.} 14 | 15 | \item{tags}{Add tags to your subfigures. Can be \code{TRUE} (letter tags) 16 | or character vector containing tags labels.} 17 | } 18 | \value{ 19 | An object of class \code{gtable}. 20 | } 21 | \description{ 22 | Plot multiple ggplot-objects as a grid-arranged single plot. 23 | } 24 | \details{ 25 | This function takes a \code{list} of ggplot-objects as argument. 26 | Plotting functions of this package that produce multiple plot 27 | objects (e.g., when there is an argument \code{facet.grid}) usually 28 | return multiple plots as list (the return value is named \code{plot.list}). 29 | To arrange these plots as grid as a single plot, use \code{plot_grid}. 30 | } 31 | \examples{ 32 | if (require("dplyr") && require("gridExtra")) { 33 | library(ggeffects) 34 | data(efc) 35 | 36 | # fit model 37 | fit <- glm( 38 | tot_sc_e ~ c12hour + e17age + e42dep + neg_c_7, 39 | data = efc, 40 | family = poisson 41 | ) 42 | 43 | # plot marginal effects for each predictor, each as single plot 44 | p1 <- ggpredict(fit, "c12hour") \%>\% 45 | plot(show_y_title = FALSE, show_title = FALSE) 46 | p2 <- ggpredict(fit, "e17age") \%>\% 47 | plot(show_y_title = FALSE, show_title = FALSE) 48 | p3 <- ggpredict(fit, "e42dep") \%>\% 49 | plot(show_y_title = FALSE, show_title = FALSE) 50 | p4 <- ggpredict(fit, "neg_c_7") \%>\% 51 | plot(show_y_title = FALSE, show_title = FALSE) 52 | 53 | # plot grid 54 | plot_grid(list(p1, p2, p3, p4)) 55 | 56 | # plot grid 57 | plot_grid(list(p1, p2, p3, p4), tags = TRUE) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /man/plot_kfold_cv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_kfold_cv.R 3 | \name{plot_kfold_cv} 4 | \alias{plot_kfold_cv} 5 | \title{Plot model fit from k-fold cross-validation} 6 | \usage{ 7 | plot_kfold_cv(data, formula, k = 5, fit) 8 | } 9 | \arguments{ 10 | \item{data}{A data frame, used to split the data into \code{k} training-test-pairs.} 11 | 12 | \item{formula}{A model formula, used to fit linear models (\code{\link[stats]{lm}}) 13 | over all \code{k} training data sets. Use \code{fit} to specify a 14 | fitted model (also other models than linear models), which will be used 15 | to compute cross validation. If \code{fit} is not missing, \code{formula} 16 | will be ignored.} 17 | 18 | \item{k}{Number of folds.} 19 | 20 | \item{fit}{Model object, which will be used to compute cross validation. If 21 | \code{fit} is not missing, \code{formula} will be ignored. Currently, 22 | only linear, poisson and negative binomial regression models are supported.} 23 | } 24 | \description{ 25 | This function plots the aggregated residuals of k-fold cross-validated 26 | models against the outcome. This allows to evaluate how the model performs 27 | according over- or underestimation of the outcome. 28 | } 29 | \details{ 30 | This function, first, generates \code{k} cross-validated test-training 31 | pairs and 32 | fits the same model, specified in the \code{formula}- or \code{fit}- 33 | argument, over all training data sets. \cr \cr 34 | Then, the test data is used to predict the outcome from all 35 | models that have been fit on the training data, and the residuals 36 | from all test data is plotted against the observed values (outcome) 37 | from the test data (note: for poisson or negative binomial models, the 38 | deviance residuals are calculated). This plot can be used to validate the model 39 | and see, whether it over- (residuals > 0) or underestimates 40 | (residuals < 0) the model's outcome. 41 | } 42 | \note{ 43 | Currently, only linear, poisson and negative binomial regression models are supported. 44 | } 45 | \examples{ 46 | data(efc) 47 | 48 | plot_kfold_cv(efc, neg_c_7 ~ e42dep + c172code + c12hour) 49 | plot_kfold_cv(mtcars, mpg ~.) 50 | 51 | # for poisson models. need to fit a model and use 'fit'-argument 52 | fit <- glm(tot_sc_e ~ neg_c_7 + c172code, data = efc, family = poisson) 53 | plot_kfold_cv(efc, fit = fit) 54 | 55 | # and for negative binomial models 56 | fit <- MASS::glm.nb(tot_sc_e ~ neg_c_7 + c172code, data = efc) 57 | plot_kfold_cv(efc, fit = fit) 58 | 59 | } 60 | -------------------------------------------------------------------------------- /man/plot_residuals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_residuals.R 3 | \name{plot_residuals} 4 | \alias{plot_residuals} 5 | \title{Plot predicted values and their residuals} 6 | \usage{ 7 | plot_residuals( 8 | fit, 9 | geom.size = 2, 10 | remove.estimates = NULL, 11 | show.lines = TRUE, 12 | show.resid = TRUE, 13 | show.pred = TRUE, 14 | show.ci = FALSE 15 | ) 16 | } 17 | \arguments{ 18 | \item{fit}{Fitted linear (mixed) regression model (including objects of class 19 | \code{\link[nlme]{gls}} or \code{plm}).} 20 | 21 | \item{geom.size}{size resp. width of the geoms (bar width, line thickness or point size, 22 | depending on plot type and function). Note that bar and bin widths mostly 23 | need smaller values than dot sizes.} 24 | 25 | \item{remove.estimates}{Numeric vector with indices (order equals to row index of \code{coef(fit)}) 26 | or character vector with coefficient names that indicate which estimates should be removed 27 | from the table output. The first estimate is the intercept, followed by the model predictors. 28 | \emph{The intercept cannot be removed from the table output!} \code{remove.estimates = c(2:4)} 29 | would remove the 2nd to the 4th estimate (1st to 3rd predictor after intercept) from the output. 30 | \code{remove.estimates = "est_name"} would remove the estimate \emph{est_name}. Default 31 | is \code{NULL}, i.e. all estimates are printed.} 32 | 33 | \item{show.lines}{Logical, if \code{TRUE}, a line connecting predicted and 34 | residual values is plotted. Set this argument to \code{FALSE}, if 35 | plot-building is too time consuming.} 36 | 37 | \item{show.resid}{Logical, if \code{TRUE}, residual values are plotted.} 38 | 39 | \item{show.pred}{Logical, if \code{TRUE}, predicted values are plotted.} 40 | 41 | \item{show.ci}{Logical, if \code{TRUE)}, adds notches to the box plot, which are 42 | used to compare groups; if the notches of two boxes do not overlap, 43 | medians are considered to be significantly different.} 44 | } 45 | \value{ 46 | A ggplot-object. 47 | } 48 | \description{ 49 | This function plots observed and predicted values of the response 50 | of linear (mixed) models for each coefficient and highlights the 51 | observed values according to their distance (residuals) to the 52 | predicted values. This allows to investigate how well actual and 53 | predicted values of the outcome fit across the predictor variables. 54 | } 55 | \note{ 56 | The actual (observed) values have a coloured fill, while the predicted 57 | values have a solid outline without filling. 58 | } 59 | \examples{ 60 | data(efc) 61 | # fit model 62 | fit <- lm(neg_c_7 ~ c12hour + e17age + e42dep, data = efc) 63 | 64 | # plot residuals for all independent variables 65 | plot_residuals(fit) 66 | 67 | # remove some independent variables from output 68 | plot_residuals(fit, remove.estimates = c("e17age", "e42dep")) 69 | 70 | } 71 | -------------------------------------------------------------------------------- /man/plot_scatter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_scatter.R 3 | \name{plot_scatter} 4 | \alias{plot_scatter} 5 | \title{Plot (grouped) scatter plots} 6 | \usage{ 7 | plot_scatter( 8 | data, 9 | x, 10 | y, 11 | grp, 12 | title = "", 13 | legend.title = NULL, 14 | legend.labels = NULL, 15 | dot.labels = NULL, 16 | axis.titles = NULL, 17 | dot.size = 1.5, 18 | label.size = 3, 19 | colors = "metro", 20 | fit.line = NULL, 21 | fit.grps = NULL, 22 | show.rug = FALSE, 23 | show.legend = TRUE, 24 | show.ci = FALSE, 25 | wrap.title = 50, 26 | wrap.legend.title = 20, 27 | wrap.legend.labels = 20, 28 | jitter = 0.05, 29 | emph.dots = FALSE, 30 | grid = FALSE 31 | ) 32 | } 33 | \arguments{ 34 | \item{data}{A data frame, or a grouped data frame.} 35 | 36 | \item{x}{Name of the variable for the x-axis.} 37 | 38 | \item{y}{Name of the variable for the y-axis.} 39 | 40 | \item{grp}{Optional, name of the grouping-variable. If not missing, the 41 | scatter plot will be grouped. See 'Examples'.} 42 | 43 | \item{title}{Character vector, used as plot title. By default, 44 | \code{\link[sjlabelled]{response_labels}} is called to retrieve the label of 45 | the dependent variable, which will be used as title. Use \code{title = ""} 46 | to remove title.} 47 | 48 | \item{legend.title}{Character vector, used as legend title for plots that 49 | have a legend.} 50 | 51 | \item{legend.labels}{character vector with labels for the guide/legend.} 52 | 53 | \item{dot.labels}{Character vector with names for each coordinate pair given 54 | by \code{x} and \code{y}, so text labels are added to the plot. 55 | Must be of same length as \code{x} and \code{y}. 56 | If \code{dot.labels} has a different length, data points will be trimmed 57 | to match \code{dot.labels}. If \code{dot.labels = NULL} (default), 58 | no labels are printed.} 59 | 60 | \item{axis.titles}{character vector of length one or two, defining the title(s) 61 | for the x-axis and y-axis.} 62 | 63 | \item{dot.size}{Numeric, size of the dots that indicate the point estimates.} 64 | 65 | \item{label.size}{Size of text labels if argument \code{dot.labels} is used.} 66 | 67 | \item{colors}{May be a character vector of color values in hex-format, valid 68 | color value names (see \code{demo("colors")}) or a name of a pre-defined 69 | color palette. Following options are valid for the \code{colors} argument: 70 | \itemize{ 71 | \item If not specified, a default color brewer palette will be used, which is suitable for the plot style. 72 | \item If \code{"gs"}, a greyscale will be used. 73 | \item If \code{"bw"}, and plot-type is a line-plot, the plot is black/white and uses different line types to distinguish groups (see \href{https://strengejacke.github.io/sjPlot/articles/blackwhitefigures.html}{this package-vignette}). 74 | \item If \code{colors} is any valid color brewer palette name, the related palette will be used. Use \code{RColorBrewer::display.brewer.all()} to view all available palette names. 75 | \item There are some pre-defined color palettes in this package, see \code{\link{sjPlot-themes}} for details. 76 | \item Else specify own color values or names as vector (e.g. \code{colors = "#00ff00"} or \code{colors = c("firebrick", "blue")}). 77 | }} 78 | 79 | \item{fit.line, fit.grps}{Specifies the method to add a fitted line accross 80 | the data points. Possible values are for instance \code{"lm"}, \code{"glm"}, 81 | \code{"loess"} or \code{"auto"}. If \code{NULL}, no line is plotted. 82 | \code{fit.line} adds a fitted line for the complete data, while \code{fit.grps} 83 | adds a fitted line for each subgroup of \code{grp}.} 84 | 85 | \item{show.rug}{Logical, if \code{TRUE}, a marginal rug plot is displayed 86 | in the graph.} 87 | 88 | \item{show.legend}{For \emph{Marginal Effects} plots, shows or hides the 89 | legend.} 90 | 91 | \item{show.ci}{Logical, if \code{TRUE)}, adds notches to the box plot, which are 92 | used to compare groups; if the notches of two boxes do not overlap, 93 | medians are considered to be significantly different.} 94 | 95 | \item{wrap.title}{Numeric, determines how many chars of the plot title are 96 | displayed in one line and when a line break is inserted.} 97 | 98 | \item{wrap.legend.title}{numeric, determines how many chars of the legend's title 99 | are displayed in one line and when a line break is inserted.} 100 | 101 | \item{wrap.legend.labels}{numeric, determines how many chars of the legend labels are 102 | displayed in one line and when a line break is inserted.} 103 | 104 | \item{jitter}{Numeric, between 0 and 1. If \code{show.data = TRUE}, you can 105 | add a small amount of random variation to the location of each data point. 106 | \code{jitter} then indicates the width, i.e. how much of a bin's width 107 | will be occupied by the jittered values.} 108 | 109 | \item{emph.dots}{Logical, if \code{TRUE}, overlapping points at same coordinates 110 | will be becomme larger, so point size indicates amount of overlapping.} 111 | 112 | \item{grid}{Logical, if \code{TRUE}, multiple plots are plotted as grid 113 | layout.} 114 | } 115 | \value{ 116 | A ggplot-object. For grouped data frames, a list of ggplot-objects for 117 | each group in the data. 118 | } 119 | \description{ 120 | Display scatter plot of two variables. Adding a grouping variable to 121 | the scatter plot is possible. Furthermore, fitted lines can be added 122 | for each group as well as for the overall plot. 123 | } 124 | \examples{ 125 | # load sample date 126 | library(sjmisc) 127 | library(sjlabelled) 128 | data(efc) 129 | 130 | # simple scatter plot 131 | plot_scatter(efc, e16sex, neg_c_7) 132 | 133 | # simple scatter plot, increased jittering 134 | plot_scatter(efc, e16sex, neg_c_7, jitter = .4) 135 | 136 | # grouped scatter plot 137 | plot_scatter(efc, c160age, e17age, e42dep) 138 | 139 | # grouped scatter plot with marginal rug plot 140 | # and add fitted line for complete data 141 | plot_scatter( 142 | efc, c12hour, c160age, c172code, 143 | show.rug = TRUE, fit.line = "lm" 144 | ) 145 | 146 | # grouped scatter plot with marginal rug plot 147 | # and add fitted line for each group 148 | plot_scatter( 149 | efc, c12hour, c160age, c172code, 150 | show.rug = TRUE, fit.grps = "loess", 151 | grid = TRUE 152 | ) 153 | 154 | } 155 | -------------------------------------------------------------------------------- /man/plot_stackfrq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_stackfrq.R 3 | \name{plot_stackfrq} 4 | \alias{plot_stackfrq} 5 | \title{Plot stacked proportional bars} 6 | \usage{ 7 | plot_stackfrq( 8 | items, 9 | title = NULL, 10 | legend.title = NULL, 11 | legend.labels = NULL, 12 | axis.titles = NULL, 13 | axis.labels = NULL, 14 | weight.by = NULL, 15 | sort.frq = NULL, 16 | wrap.title = 50, 17 | wrap.labels = 30, 18 | wrap.legend.title = 30, 19 | wrap.legend.labels = 28, 20 | geom.size = 0.5, 21 | geom.colors = "Blues", 22 | show.prc = TRUE, 23 | show.n = FALSE, 24 | show.total = TRUE, 25 | show.axis.prc = TRUE, 26 | show.legend = TRUE, 27 | grid.breaks = 0.2, 28 | expand.grid = FALSE, 29 | digits = 1, 30 | vjust = "center", 31 | coord.flip = TRUE 32 | ) 33 | } 34 | \arguments{ 35 | \item{items}{Data frame, or a grouped data frame, with each column representing one item.} 36 | 37 | \item{title}{character vector, used as plot title. Depending on plot type and function, 38 | will be set automatically. If \code{title = ""}, no title is printed. 39 | For effect-plots, may also be a character vector of length > 1, 40 | to define titles for each sub-plot or facet.} 41 | 42 | \item{legend.title}{character vector, used as title for the plot legend.} 43 | 44 | \item{legend.labels}{character vector with labels for the guide/legend.} 45 | 46 | \item{axis.titles}{character vector of length one or two, defining the title(s) 47 | for the x-axis and y-axis.} 48 | 49 | \item{axis.labels}{character vector with labels used as axis labels. Optional 50 | argument, since in most cases, axis labels are set automatically.} 51 | 52 | \item{weight.by}{Vector of weights that will be applied to weight all cases. 53 | Must be a vector of same length as the input vector. Default is 54 | \code{NULL}, so no weights are used.} 55 | 56 | \item{sort.frq}{Indicates whether the \code{items} should be ordered by 57 | by highest count of first or last category of \code{items}. 58 | \describe{ 59 | \item{\code{"first.asc"}}{to order ascending by lowest count of first category,} 60 | \item{\code{"first.desc"}}{to order descending by lowest count of first category,} 61 | \item{\code{"last.asc"}}{to order ascending by lowest count of last category,} 62 | \item{\code{"last.desc"}}{to order descending by lowest count of last category,} 63 | \item{\code{NULL}}{(default) for no sorting.} 64 | }} 65 | 66 | \item{wrap.title}{numeric, determines how many chars of the plot title are displayed in 67 | one line and when a line break is inserted.} 68 | 69 | \item{wrap.labels}{numeric, determines how many chars of the value, variable or axis 70 | labels are displayed in one line and when a line break is inserted.} 71 | 72 | \item{wrap.legend.title}{numeric, determines how many chars of the legend's title 73 | are displayed in one line and when a line break is inserted.} 74 | 75 | \item{wrap.legend.labels}{numeric, determines how many chars of the legend labels are 76 | displayed in one line and when a line break is inserted.} 77 | 78 | \item{geom.size}{size resp. width of the geoms (bar width, line thickness or point size, 79 | depending on plot type and function). Note that bar and bin widths mostly 80 | need smaller values than dot sizes.} 81 | 82 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 83 | 84 | \item{show.prc}{Logical, whether percentage values should be plotted or not.} 85 | 86 | \item{show.n}{Logical, whether count values hould be plotted or not.} 87 | 88 | \item{show.total}{logical, if \code{TRUE}, adds total number of cases for each 89 | group or category to the labels.} 90 | 91 | \item{show.axis.prc}{Logical, if \code{TRUE} (default), the percentage values at the x-axis are shown.} 92 | 93 | \item{show.legend}{logical, if \code{TRUE}, and depending on plot type and 94 | function, a legend is added to the plot.} 95 | 96 | \item{grid.breaks}{numeric; sets the distance between breaks for the axis, 97 | i.e. at every \code{grid.breaks}'th position a major grid is being printed.} 98 | 99 | \item{expand.grid}{logical, if \code{TRUE}, the plot grid is expanded, i.e. there is a small margin between 100 | axes and plotting region. Default is \code{FALSE}.} 101 | 102 | \item{digits}{Numeric, amount of digits after decimal point when rounding 103 | estimates or values.} 104 | 105 | \item{vjust}{character vector, indicating the vertical position of value 106 | labels. Allowed are same values as for \code{vjust} aesthetics from 107 | \code{ggplot2}: "left", "center", "right", "bottom", "middle", "top" and 108 | new options like "inward" and "outward", which align text towards and 109 | away from the center of the plot respectively.} 110 | 111 | \item{coord.flip}{logical, if \code{TRUE}, the x and y axis are swapped.} 112 | } 113 | \value{ 114 | A ggplot-object. 115 | } 116 | \description{ 117 | Plot items (variables) of a scale as stacked proportional bars. This 118 | function is useful when several items with identical scale/categoroies 119 | should be plotted to compare the distribution of answers. 120 | } 121 | \examples{ 122 | # Data from the EUROFAMCARE sample dataset 123 | library(sjmisc) 124 | data(efc) 125 | # recveive first item of COPE-index scale 126 | start <- which(colnames(efc) == "c82cop1") 127 | # recveive first item of COPE-index scale 128 | end <- which(colnames(efc) == "c90cop9") 129 | # auto-detection of labels 130 | plot_stackfrq(efc[, start:end]) 131 | 132 | # works on grouped data frames as well 133 | library(dplyr) 134 | efc \%>\% 135 | group_by(c161sex) \%>\% 136 | select(start:end) \%>\% 137 | plot_stackfrq() 138 | 139 | } 140 | -------------------------------------------------------------------------------- /man/save_plot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/save_plot.R 3 | \name{save_plot} 4 | \alias{save_plot} 5 | \title{Save ggplot-figure for print publication} 6 | \usage{ 7 | save_plot( 8 | filename, 9 | fig = last_plot(), 10 | width = 12, 11 | height = 9, 12 | dpi = 300, 13 | theme = theme_get(), 14 | label.color = "black", 15 | label.size = 2.4, 16 | axis.textsize = 0.8, 17 | axis.titlesize = 0.75, 18 | legend.textsize = 0.6, 19 | legend.titlesize = 0.65, 20 | legend.itemsize = 0.5 21 | ) 22 | } 23 | \arguments{ 24 | \item{filename}{Name of the output file; filename must end with one 25 | of the following accepted file types: ".png", ".jpg", ".svg" or ".tif".} 26 | 27 | \item{fig}{The plot that should be saved. By default, the last plot is saved.} 28 | 29 | \item{width}{Width of the figure, in centimetres.} 30 | 31 | \item{height}{Height of the figure, in centimetres.} 32 | 33 | \item{dpi}{Resolution in dpi (dots per inch). Ignored for vector formats, such as ".svg".} 34 | 35 | \item{theme}{The default theme to use when saving the plot.} 36 | 37 | \item{label.color}{Color value for labels (axis, plot, etc.).} 38 | 39 | \item{label.size}{Fontsize of value labels inside plot area.} 40 | 41 | \item{axis.textsize}{Fontsize of axis labels.} 42 | 43 | \item{axis.titlesize}{Fontsize of axis titles.} 44 | 45 | \item{legend.textsize}{Fontsize of legend labels.} 46 | 47 | \item{legend.titlesize}{Fontsize of legend title.} 48 | 49 | \item{legend.itemsize}{Size of legend's item (legend key), in centimetres.} 50 | } 51 | \description{ 52 | Convenient function to save the last ggplot-figure in 53 | high quality for publication. 54 | } 55 | \note{ 56 | This is a convenient function with some default settings that should 57 | come close to most of the needs for fontsize and scaling in figures 58 | when saving them for printing or publishing. It uses cairographics 59 | anti-aliasing (see \code{\link[grDevices]{png}}). 60 | \cr \cr 61 | For adjusting plot appearance, see also \code{\link{sjPlot-themes}}. 62 | } 63 | -------------------------------------------------------------------------------- /man/sjPlot-package.Rd: -------------------------------------------------------------------------------- 1 | \encoding{UTF-8} 2 | \name{sjPlot-package} 3 | \alias{sjPlot-package} 4 | \alias{sjPlot} 5 | \docType{package} 6 | \title{Data Visualization for Statistics in Social Science} 7 | \description{ 8 | Collection of plotting and table output functions for data visualization. Results of various statistical analyses (that are commonly used in social sciences) can be visualized using this package, including simple and cross tabulated frequencies, histograms, box plots, (generalized) linear models, mixed effects models, PCA and correlation matrices, cluster analyses, scatter plots, Likert scales, effects plots of interaction terms in regression models, constructing index or score variables and much more. 9 | 10 | The package supports labelled data, i.e. value and variable labels from labelled data (like vectors or data frames) are automatically used to label the output. Own labels can be specified as well. 11 | 12 | \emph{What does this package do?} 13 | 14 | In short, the functions in this package mostly do two things: 15 | \enumerate{ 16 | \item compute basic or advanced statistical analyses 17 | \item either plot the results as ggplot-figure or print them as html-table 18 | } 19 | 20 | \emph{How does this package help me?} 21 | 22 | One of the more challenging tasks when working with R is to get nicely formatted output of statistical analyses, either in graphical or table format. The sjPlot-package takes over these tasks and makes it easy to create beautiful figures or tables. 23 | 24 | There are many examples for each function in the related help files and a comprehensive online documentation at \url{https://strengejacke.github.io/sjPlot/}. 25 | 26 | \emph{A note on the package functions} 27 | 28 | The main functions follow specific naming conventions, hence starting with a specific prefix, which indicates what kind of task these functions perform. 29 | \itemize{ 30 | \item \code{sjc} - cluster analysis functions 31 | \item \code{sjp} - plotting functions 32 | \item \code{sjt} - (HTML) table output functions 33 | } 34 | } 35 | 36 | \author{ 37 | Daniel Lüdecke \email{d.luedecke@uke.de} 38 | } 39 | -------------------------------------------------------------------------------- /man/sjPlot-themes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjplot_themes.R 3 | \name{sjPlot-themes} 4 | \alias{sjPlot-themes} 5 | \alias{theme_sjplot} 6 | \alias{theme_sjplot2} 7 | \alias{theme_blank} 8 | \alias{theme_538} 9 | \alias{font_size} 10 | \alias{label_angle} 11 | \alias{legend_style} 12 | \alias{scale_color_sjplot} 13 | \alias{scale_fill_sjplot} 14 | \alias{sjplot_pal} 15 | \alias{show_sjplot_pals} 16 | \alias{css_theme} 17 | \title{Modify plot appearance} 18 | \usage{ 19 | theme_sjplot(base_size = 12, base_family = "") 20 | 21 | theme_sjplot2(base_size = 12, base_family = "") 22 | 23 | theme_blank(base_size = 12, base_family = "") 24 | 25 | theme_538(base_size = 12, base_family = "") 26 | 27 | font_size( 28 | title, 29 | axis_title.x, 30 | axis_title.y, 31 | labels.x, 32 | labels.y, 33 | offset.x, 34 | offset.y, 35 | base.theme 36 | ) 37 | 38 | label_angle(angle.x, angle.y, base.theme) 39 | 40 | legend_style(inside, pos, justify, base.theme) 41 | 42 | scale_color_sjplot(palette = "metro", discrete = TRUE, reverse = FALSE, ...) 43 | 44 | scale_fill_sjplot(palette = "metro", discrete = TRUE, reverse = FALSE, ...) 45 | 46 | sjplot_pal(palette = "metro", n = NULL) 47 | 48 | show_sjplot_pals() 49 | 50 | css_theme(css.theme = "regression") 51 | } 52 | \arguments{ 53 | \item{base_size}{Base font size.} 54 | 55 | \item{base_family}{Base font family.} 56 | 57 | \item{title}{Font size for plot titles.} 58 | 59 | \item{axis_title.x}{Font size for x-axis titles.} 60 | 61 | \item{axis_title.y}{Font size for y-axis titles.} 62 | 63 | \item{labels.x}{Font size for x-axis labels.} 64 | 65 | \item{labels.y}{Font size for y-axis labels.} 66 | 67 | \item{offset.x}{Offset for x-axis titles.} 68 | 69 | \item{offset.y}{Offset for y-axis titles.} 70 | 71 | \item{base.theme}{Optional ggplot-theme-object, which is needed in case multiple 72 | functions should be combined, e.g. \code{theme_sjplot() + label_angle()}. 73 | In such cases, use \code{label_angle(base.theme = theme_sjplot())}.} 74 | 75 | \item{angle.x}{Angle for x-axis labels.} 76 | 77 | \item{angle.y}{Angle for y-axis labels.} 78 | 79 | \item{inside}{Logical, use \code{TRUE} to put legend inside the plotting area. 80 | See also \code{pos}.} 81 | 82 | \item{pos}{Position of the legend, if a legend is drawn. 83 | \describe{ 84 | \item{\emph{Legend outside plot}}{ 85 | Use \code{"bottom"}, \code{"top"}, \code{"left"} or \code{"right"} 86 | to position the legend above, below, on the left or right side 87 | of the diagram. 88 | } 89 | \item{\emph{Legend inside plot}}{ 90 | If \code{inside = TRUE}, legend can be placed inside 91 | plot. Use \code{"top left"}, \code{"top right"}, \code{"bottom left"} 92 | and \code{"bottom right"} to position legend in any of these corners, 93 | or a two-element numeric vector with values from 0-1. See also 94 | \code{inside}. 95 | } 96 | }} 97 | 98 | \item{justify}{Justification of legend, relative to its position (\code{"center"} or 99 | two-element numeric vector with values from 0-1.} 100 | 101 | \item{palette}{Character name of color palette.} 102 | 103 | \item{discrete}{Logical, if \code{TRUE}, a discrete colour palette is returned. 104 | Else, a gradient palette is returned, where colours of the requested palette 105 | are interpolated using \code{\link[grDevices]{colorRampPalette}}.} 106 | 107 | \item{reverse}{Logical, if \code{TRUE}, order of returned colours is reversed.} 108 | 109 | \item{...}{Further arguments passed down to ggplot's \code{scale()}-functions.} 110 | 111 | \item{n}{Numeric, number of colors to be returned. By default, the complete 112 | colour palette is returned.} 113 | 114 | \item{css.theme}{Name of the CSS pre-set theme-style. Can be used for table-functions.} 115 | } 116 | \description{ 117 | Set default plot themes, use pre-defined color scales or modify 118 | plot or table appearance. 119 | } 120 | \details{ 121 | When using the \code{colors} argument in function calls (e.g. 122 | \code{plot_model()}) or when calling one of the predefined scale-functions 123 | (e.g. \code{scale_color_sjplot()}), there are pre-defined colour palettes 124 | in this package. Use \code{show_sjplot_pals()} to show all available 125 | colour palettes. 126 | } 127 | \examples{ 128 | # prepare data 129 | if (requireNamespace("haven")) { 130 | library(sjmisc) 131 | data(efc) 132 | efc <- to_factor(efc, c161sex, e42dep, c172code) 133 | m <- lm(neg_c_7 ~ pos_v_4 + c12hour + e42dep + c172code, data = efc) 134 | 135 | # create plot-object 136 | p <- plot_model(m) 137 | 138 | # change theme 139 | p + theme_sjplot() 140 | 141 | # change font-size 142 | p + font_size(axis_title.x = 30) 143 | 144 | # apply color theme 145 | p + scale_color_sjplot() 146 | 147 | # show all available colour palettes 148 | show_sjplot_pals() 149 | 150 | # get colour values from specific palette 151 | sjplot_pal(pal = "breakfast club") 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /man/sjp.aov1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotAnova.R 3 | \name{sjp.aov1} 4 | \alias{sjp.aov1} 5 | \title{Plot One-Way-Anova tables} 6 | \usage{ 7 | sjp.aov1( 8 | var.dep, 9 | var.grp, 10 | meansums = FALSE, 11 | title = NULL, 12 | axis.labels = NULL, 13 | rev.order = FALSE, 14 | string.interc = "(Intercept)", 15 | axis.title = "", 16 | axis.lim = NULL, 17 | geom.colors = c("#3366a0", "#aa3333"), 18 | geom.size = 3, 19 | wrap.title = 50, 20 | wrap.labels = 25, 21 | grid.breaks = NULL, 22 | show.values = TRUE, 23 | digits = 2, 24 | y.offset = 0.15, 25 | show.p = TRUE, 26 | show.summary = FALSE 27 | ) 28 | } 29 | \arguments{ 30 | \item{var.dep}{Dependent variable. Will be used with following formula: 31 | \code{aov(var.dep ~ var.grp)}} 32 | 33 | \item{var.grp}{Factor with the cross-classifying variable, where \code{var.dep} 34 | is grouped into the categories represented by \code{var.grp}.} 35 | 36 | \item{meansums}{Logical, if \code{TRUE}, the values reported are the true group mean values. 37 | If \code{FALSE} (default), the values are reported in the standard way, i.e. the values indicate the difference of 38 | the group mean in relation to the intercept (reference group).} 39 | 40 | \item{title}{character vector, used as plot title. Depending on plot type and function, 41 | will be set automatically. If \code{title = ""}, no title is printed. 42 | For effect-plots, may also be a character vector of length > 1, 43 | to define titles for each sub-plot or facet.} 44 | 45 | \item{axis.labels}{character vector with labels used as axis labels. Optional 46 | argument, since in most cases, axis labels are set automatically.} 47 | 48 | \item{rev.order}{Logical, if \code{TRUE}, order of categories (groups) is reversed.} 49 | 50 | \item{string.interc}{Character vector that indicates the reference group (intercept), that is appended to 51 | the value label of the grouping variable. Default is \code{"(Intercept)"}.} 52 | 53 | \item{axis.title}{Character vector of length one or two (depending on the 54 | plot function and type), used as title(s) for the x and y axis. If not 55 | specified, a default labelling is chosen. \strong{Note:} Some plot types 56 | may not support this argument sufficiently. In such cases, use the returned 57 | ggplot-object and add axis titles manually with 58 | \code{\link[ggplot2]{labs}}. Use \code{axis.title = ""} to remove axis 59 | titles.} 60 | 61 | \item{axis.lim}{Numeric vector of length 2, defining the range of the plot axis. 62 | Depending on plot type, may effect either x- or y-axis, or both. 63 | For multiple plot outputs (e.g., from \code{type = "eff"} or 64 | \code{type = "slope"} in \code{\link{plot_model}}), \code{axis.lim} may 65 | also be a list of vectors of length 2, defining axis limits for each 66 | plot (only if non-faceted).} 67 | 68 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 69 | 70 | \item{geom.size}{size resp. width of the geoms (bar width, line thickness or point size, 71 | depending on plot type and function). Note that bar and bin widths mostly 72 | need smaller values than dot sizes.} 73 | 74 | \item{wrap.title}{numeric, determines how many chars of the plot title are displayed in 75 | one line and when a line break is inserted.} 76 | 77 | \item{wrap.labels}{numeric, determines how many chars of the value, variable or axis 78 | labels are displayed in one line and when a line break is inserted.} 79 | 80 | \item{grid.breaks}{numeric; sets the distance between breaks for the axis, 81 | i.e. at every \code{grid.breaks}'th position a major grid is being printed.} 82 | 83 | \item{show.values}{Logical, whether values should be plotted or not.} 84 | 85 | \item{digits}{Numeric, amount of digits after decimal point when rounding 86 | estimates or values.} 87 | 88 | \item{y.offset}{numeric, offset for text labels when their alignment is adjusted 89 | to the top/bottom of the geom (see \code{hjust} and \code{vjust}).} 90 | 91 | \item{show.p}{Logical, adds significance levels to values, or value and 92 | variable labels.} 93 | 94 | \item{show.summary}{logical, if \code{TRUE} (default), a summary with chi-squared 95 | statistics (see \code{\link{chisq.test}}), Cramer's V or Phi-value etc. 96 | is shown. If a cell contains expected values lower than five (or lower than 10 97 | if df is 1), the Fisher's exact test (see \code{\link{fisher.test}}) is 98 | computed instead of chi-squared test. If the table's matrix is larger 99 | than 2x2, Fisher's exact test with Monte Carlo simulation is computed.} 100 | } 101 | \value{ 102 | A ggplot-object. 103 | } 104 | \description{ 105 | Plot One-Way-Anova table sum of squares (SS) of each factor level (group) 106 | against the dependent variable. The SS of the factor variable against the 107 | dependent variable (variance within and between groups) is printed to 108 | the model summary. 109 | } 110 | \examples{ 111 | data(efc) 112 | # note: "var.grp" does not need to be a factor. 113 | # coercion to factor is done by the function 114 | sjp.aov1(efc$c12hour, efc$e42dep) 115 | 116 | 117 | } 118 | -------------------------------------------------------------------------------- /man/sjp.chi2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotPearsonsChi2Test.R 3 | \name{sjp.chi2} 4 | \alias{sjp.chi2} 5 | \title{Plot Pearson's Chi2-Test of multiple contingency tables} 6 | \usage{ 7 | sjp.chi2( 8 | df, 9 | title = "Pearson's Chi2-Test of Independence", 10 | axis.labels = NULL, 11 | wrap.title = 50, 12 | wrap.labels = 20, 13 | show.legend = FALSE, 14 | legend.title = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{df}{A data frame with (dichotomous) factor variables.} 19 | 20 | \item{title}{character vector, used as plot title. Depending on plot type and function, 21 | will be set automatically. If \code{title = ""}, no title is printed. 22 | For effect-plots, may also be a character vector of length > 1, 23 | to define titles for each sub-plot or facet.} 24 | 25 | \item{axis.labels}{character vector with labels used as axis labels. Optional 26 | argument, since in most cases, axis labels are set automatically.} 27 | 28 | \item{wrap.title}{numeric, determines how many chars of the plot title are displayed in 29 | one line and when a line break is inserted.} 30 | 31 | \item{wrap.labels}{numeric, determines how many chars of the value, variable or axis 32 | labels are displayed in one line and when a line break is inserted.} 33 | 34 | \item{show.legend}{logical, if \code{TRUE}, and depending on plot type and 35 | function, a legend is added to the plot.} 36 | 37 | \item{legend.title}{character vector, used as title for the plot legend.} 38 | } 39 | \value{ 40 | A ggplot-object. 41 | } 42 | \description{ 43 | Plot p-values of Pearson's Chi2-tests for multiple contingency tables as ellipses or tiles. 44 | Requires a data frame with dichotomous (dummy) variables. 45 | Calculation of Chi2-matrix taken from 46 | \href{https://talesofr.wordpress.com/2013/05/05/ridiculously-photogenic-factors-heatmap-with-p-values/}{Tales of R}. 47 | } 48 | \examples{ 49 | # create data frame with 5 dichotomous (dummy) variables 50 | mydf <- data.frame(as.factor(sample(1:2, 100, replace=TRUE)), 51 | as.factor(sample(1:2, 100, replace=TRUE)), 52 | as.factor(sample(1:2, 100, replace=TRUE)), 53 | as.factor(sample(1:2, 100, replace=TRUE)), 54 | as.factor(sample(1:2, 100, replace=TRUE))) 55 | # create variable labels 56 | items <- list(c("Item 1", "Item 2", "Item 3", "Item 4", "Item 5")) 57 | 58 | # plot Chi2-contingency-table 59 | sjp.chi2(mydf, axis.labels = items) 60 | 61 | } 62 | -------------------------------------------------------------------------------- /man/sjp.corr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotCorr.R 3 | \name{sjp.corr} 4 | \alias{sjp.corr} 5 | \title{Plot correlation matrix} 6 | \usage{ 7 | sjp.corr( 8 | data, 9 | title = NULL, 10 | axis.labels = NULL, 11 | sort.corr = TRUE, 12 | decimals = 3, 13 | na.deletion = c("listwise", "pairwise"), 14 | corr.method = c("pearson", "spearman", "kendall"), 15 | geom.colors = "RdBu", 16 | wrap.title = 50, 17 | wrap.labels = 20, 18 | show.legend = FALSE, 19 | legend.title = NULL, 20 | show.values = TRUE, 21 | show.p = TRUE, 22 | p.numeric = FALSE 23 | ) 24 | } 25 | \arguments{ 26 | \item{data}{Matrix with correlation coefficients as returned by the 27 | \code{\link{cor}}-function, or a \code{data.frame} of variables where 28 | correlations between columns should be computed.} 29 | 30 | \item{title}{character vector, used as plot title. Depending on plot type and function, 31 | will be set automatically. If \code{title = ""}, no title is printed. 32 | For effect-plots, may also be a character vector of length > 1, 33 | to define titles for each sub-plot or facet.} 34 | 35 | \item{axis.labels}{character vector with labels used as axis labels. Optional 36 | argument, since in most cases, axis labels are set automatically.} 37 | 38 | \item{sort.corr}{Logical, if \code{TRUE} (default), the axis labels are sorted 39 | according to the correlation strength. If \code{FALSE}, axis labels 40 | appear in order of how variables were included in the cor-computation or 41 | data frame.} 42 | 43 | \item{decimals}{Indicates how many decimal values after comma are printed when 44 | the values labels are shown. Default is 3. Only applies when 45 | \code{show.values = TRUE}.} 46 | 47 | \item{na.deletion}{Indicates how missing values are treated. May be either 48 | \code{"listwise"} (default) or \code{"pairwise"}. May be 49 | abbreviated.} 50 | 51 | \item{corr.method}{Indicates the correlation computation method. May be one of 52 | \code{"pearson"} (default), \code{"spearman"} or \code{"kendall"}. 53 | May be abbreviated.} 54 | 55 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 56 | 57 | \item{wrap.title}{numeric, determines how many chars of the plot title are displayed in 58 | one line and when a line break is inserted.} 59 | 60 | \item{wrap.labels}{numeric, determines how many chars of the value, variable or axis 61 | labels are displayed in one line and when a line break is inserted.} 62 | 63 | \item{show.legend}{logical, if \code{TRUE}, and depending on plot type and 64 | function, a legend is added to the plot.} 65 | 66 | \item{legend.title}{character vector, used as title for the plot legend.} 67 | 68 | \item{show.values}{Logical, whether values should be plotted or not.} 69 | 70 | \item{show.p}{Logical, adds significance levels to values, or value and 71 | variable labels.} 72 | 73 | \item{p.numeric}{Logical, if \code{TRUE}, the p-values are printed 74 | as numbers. If \code{FALSE} (default), asterisks are used.} 75 | } 76 | \value{ 77 | (Insisibily) returns the ggplot-object with the complete plot (\code{plot}) as well as the data frame that 78 | was used for setting up the ggplot-object (\code{df}) and the original correlation matrix 79 | (\code{corr.matrix}). 80 | } 81 | \description{ 82 | Plot correlation matrix as ellipses or tiles. 83 | } 84 | \details{ 85 | Required argument is either a \code{\link{data.frame}} or a matrix with correlation coefficients 86 | as returned by the \code{\link{cor}}-function. In case of ellipses, the 87 | ellipses size indicates the strength of the correlation. Furthermore, 88 | blue and red colors indicate positive or negative correlations, where 89 | stronger correlations are darker. 90 | } 91 | \note{ 92 | If \code{data} is a matrix with correlation coefficients as returned by 93 | the \code{\link{cor}}-function, p-values can't be computed. 94 | Thus, \code{show.p} and \code{p.numeric} 95 | only have an effect if \code{data} is a \code{\link{data.frame}}. 96 | } 97 | -------------------------------------------------------------------------------- /man/sjp.poly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjPlotPolynomials.R 3 | \name{sjp.poly} 4 | \alias{sjp.poly} 5 | \title{Plot polynomials for (generalized) linear regression} 6 | \usage{ 7 | sjp.poly( 8 | x, 9 | poly.term, 10 | poly.degree, 11 | poly.scale = FALSE, 12 | fun = NULL, 13 | axis.title = NULL, 14 | geom.colors = NULL, 15 | geom.size = 0.8, 16 | show.loess = TRUE, 17 | show.loess.ci = TRUE, 18 | show.p = TRUE, 19 | show.scatter = TRUE, 20 | point.alpha = 0.2, 21 | point.color = "#404040", 22 | loess.color = "#808080" 23 | ) 24 | } 25 | \arguments{ 26 | \item{x}{A vector, representing the response variable of a linear (mixed) model; or 27 | a linear (mixed) model as returned by \code{\link{lm}} or \code{\link[lme4]{lmer}}.} 28 | 29 | \item{poly.term}{If \code{x} is a vector, \code{poly.term} should also be a vector, representing 30 | the polynomial term (independent variabl) in the model; if \code{x} is a 31 | fitted model, \code{poly.term} should be the polynomial term's name as character string. 32 | See 'Examples'.} 33 | 34 | \item{poly.degree}{Numeric, or numeric vector, indicating the degree of the polynomial. 35 | If \code{poly.degree} is a numeric vector, multiple polynomial curves for 36 | each degree are plotted. See 'Examples'.} 37 | 38 | \item{poly.scale}{Logical, if \code{TRUE}, \code{poly.term} will be scaled before 39 | linear regression is computed. Default is \code{FALSE}. Scaling the polynomial 40 | term may have an impact on the resulting p-values.} 41 | 42 | \item{fun}{Linear function when modelling polynomial terms. Use \code{fun = "lm"} 43 | for linear models, or \code{fun = "glm"} for generalized linear models. 44 | When \code{x} is not a vector, but a fitted model object, the function 45 | is detected automatically. If \code{x} is a vector, \code{fun} defaults 46 | to \code{"lm"}.} 47 | 48 | \item{axis.title}{Character vector of length one or two (depending on the 49 | plot function and type), used as title(s) for the x and y axis. If not 50 | specified, a default labelling is chosen. \strong{Note:} Some plot types 51 | may not support this argument sufficiently. In such cases, use the returned 52 | ggplot-object and add axis titles manually with 53 | \code{\link[ggplot2]{labs}}. Use \code{axis.title = ""} to remove axis 54 | titles.} 55 | 56 | \item{geom.colors}{user defined color for geoms. See 'Details' in \code{\link{plot_grpfrq}}.} 57 | 58 | \item{geom.size}{size resp. width of the geoms (bar width, line thickness or point size, 59 | depending on plot type and function). Note that bar and bin widths mostly 60 | need smaller values than dot sizes.} 61 | 62 | \item{show.loess}{Logical, if \code{TRUE}, an additional loess-smoothed line is plotted.} 63 | 64 | \item{show.loess.ci}{Logical, if \code{TRUE}, a confidence region for the loess-smoothed line 65 | will be plotted.} 66 | 67 | \item{show.p}{Logical, if \code{TRUE} (default), p-values for polynomial terms are 68 | printed to the console.} 69 | 70 | \item{show.scatter}{Logical, if TRUE (default), adds a scatter plot of data 71 | points to the plot.} 72 | 73 | \item{point.alpha}{Alpha value of point-geoms in the scatter plots. Only 74 | applies, if \code{show.scatter = TRUE}.} 75 | 76 | \item{point.color}{Color of of point-geoms in the scatter plots. Only applies, 77 | if \code{show.scatter = TRUE.}} 78 | 79 | \item{loess.color}{Color of the loess-smoothed line. Only applies, if \code{show.loess = TRUE}.} 80 | } 81 | \value{ 82 | A ggplot-object. 83 | } 84 | \description{ 85 | This function plots a scatter plot of a term \code{poly.term} 86 | against a response variable \code{x} and adds - depending on 87 | the amount of numeric values in \code{poly.degree} - multiple 88 | polynomial curves. A loess-smoothed line can be added to see 89 | which of the polynomial curves fits best to the data. 90 | } 91 | \details{ 92 | For each polynomial degree, a simple linear regression on \code{x} (resp. 93 | the extracted response, if \code{x} is a fitted model) is performed, 94 | where only the polynomial term \code{poly.term} is included as independent variable. 95 | Thus, \code{lm(y ~ x + I(x^2) + ... + I(x^i))} is repeatedly computed 96 | for all values in \code{poly.degree}, and the predicted values of 97 | the reponse are plotted against the raw values of \code{poly.term}. 98 | If \code{x} is a fitted model, other covariates are ignored when 99 | finding the best fitting polynomial. \cr \cr 100 | This function evaluates raw polynomials, \emph{not orthogonal} polynomials. 101 | Polynomials are computed using the \code{\link{poly}} function, 102 | with argument \code{raw = TRUE}. \cr \cr 103 | To find out which polynomial degree fits best to the data, a loess-smoothed 104 | line (in dark grey) can be added (with \code{show.loess = TRUE}). The polynomial curves 105 | that comes closest to the loess-smoothed line should be the best 106 | fit to the data. 107 | } 108 | \examples{ 109 | library(sjmisc) 110 | data(efc) 111 | # linear fit. loess-smoothed line indicates a more 112 | # or less cubic curve 113 | sjp.poly(efc$c160age, efc$quol_5, 1) 114 | 115 | # quadratic fit 116 | sjp.poly(efc$c160age, efc$quol_5, 2) 117 | 118 | # linear to cubic fit 119 | sjp.poly(efc$c160age, efc$quol_5, 1:4, show.scatter = FALSE) 120 | 121 | 122 | # fit sample model 123 | fit <- lm(tot_sc_e ~ c12hour + e17age + e42dep, data = efc) 124 | # inspect relationship between predictors and response 125 | plot_model(fit, type = "slope") 126 | # "e17age" does not seem to be linear correlated to response 127 | # try to find appropiate polynomial. Grey line (loess smoothed) 128 | # indicates best fit. Looks like x^4 has the best fit, 129 | # however, only x^3 has significant p-values. 130 | sjp.poly(fit, "e17age", 2:4, show.scatter = FALSE) 131 | 132 | \dontrun{ 133 | # fit new model 134 | fit <- lm(tot_sc_e ~ c12hour + e42dep + e17age + I(e17age^2) + I(e17age^3), 135 | data = efc) 136 | # plot marginal effects of polynomial term 137 | plot_model(fit, type = "pred", terms = "e17age")} 138 | 139 | } 140 | -------------------------------------------------------------------------------- /man/sjplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sjplot.R 3 | \name{sjplot} 4 | \alias{sjplot} 5 | \alias{sjtab} 6 | \title{Wrapper to create plots and tables within a pipe-workflow} 7 | \usage{ 8 | sjplot(data, ..., fun = c("grpfrq", "xtab", "aov1", "likert")) 9 | 10 | sjtab(data, ..., fun = c("xtab", "stackfrq")) 11 | } 12 | \arguments{ 13 | \item{data}{A data frame. May also be a grouped data frame (see 'Note' and 14 | 'Examples').} 15 | 16 | \item{...}{Names of variables that should be plotted, and also further 17 | arguments passed down to the \pkg{sjPlot}-functions. See 'Examples'.} 18 | 19 | \item{fun}{Plotting function. Refers to the function name of \pkg{sjPlot}-functions. 20 | See 'Details' and 'Examples'.} 21 | } 22 | \value{ 23 | See related sjp. and sjt.-functions. 24 | } 25 | \description{ 26 | This function has a pipe-friendly argument-structure, with the 27 | first argument always being the data, followed by variables that 28 | should be plotted or printed as table. The function then transforms 29 | the input and calls the requested sjp.- resp. sjt.-function 30 | to create a plot or table. \cr \cr 31 | Both \code{sjplot()} and \code{sjtab()} support grouped data frames. 32 | } 33 | \details{ 34 | Following \code{fun}-values are currently supported: 35 | \describe{ 36 | \item{\code{"aov1"}}{calls \code{\link{sjp.aov1}}. The first 37 | two variables in \code{data} are used (and required) to create the plot. 38 | } 39 | \item{\code{"grpfrq"}}{calls \code{\link{plot_grpfrq}}. The first 40 | two variables in \code{data} are used (and required) to create the plot. 41 | } 42 | \item{\code{"likert"}}{calls \code{\link{plot_likert}}. \code{data} 43 | must be a data frame with items to plot. 44 | } 45 | \item{\code{"stackfrq"}}{calls \code{\link{tab_stackfrq}}. 46 | \code{data} must be a data frame with items to create the table. 47 | } 48 | \item{\code{"xtab"}}{calls \code{\link{plot_xtab}} or \code{\link{tab_xtab}}. 49 | The first two variables in \code{data} are used (and required) 50 | to create the plot or table. 51 | } 52 | } 53 | } 54 | \note{ 55 | The \code{...}-argument is used, first, to specify the variables from \code{data} 56 | that should be plotted, and, second, to name further arguments that are 57 | used in the subsequent plotting functions. Refer to the online-help of 58 | supported plotting-functions to see valid arguments. 59 | \cr \cr 60 | \code{data} may also be a grouped data frame (see \code{\link[dplyr]{group_by}}) 61 | with up to two grouping variables. Plots are created for each subgroup then. 62 | } 63 | \examples{ 64 | library(dplyr) 65 | data(efc) 66 | 67 | # Grouped frequencies 68 | efc \%>\% sjplot(e42dep, c172code, fun = "grpfrq") 69 | 70 | # Grouped frequencies, as box plots 71 | efc \%>\% sjplot(e17age, c172code, fun = "grpfrq", 72 | type = "box", geom.colors = "Set1") 73 | 74 | \dontrun{ 75 | # table output of grouped data frame 76 | efc \%>\% 77 | group_by(e16sex, c172code) \%>\% 78 | select(e42dep, n4pstu, e16sex, c172code) \%>\% 79 | sjtab(fun = "xtab", use.viewer = FALSE) # open all tables in browser} 80 | 81 | } 82 | -------------------------------------------------------------------------------- /man/tab_corr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tab_corr.R 3 | \name{tab_corr} 4 | \alias{tab_corr} 5 | \title{Summary of correlations as HTML table} 6 | \usage{ 7 | tab_corr( 8 | data, 9 | na.deletion = c("listwise", "pairwise"), 10 | corr.method = c("pearson", "spearman", "kendall"), 11 | title = NULL, 12 | var.labels = NULL, 13 | wrap.labels = 40, 14 | show.p = TRUE, 15 | p.numeric = FALSE, 16 | fade.ns = TRUE, 17 | val.rm = NULL, 18 | digits = 3, 19 | triangle = "both", 20 | string.diag = NULL, 21 | CSS = NULL, 22 | encoding = NULL, 23 | file = NULL, 24 | use.viewer = TRUE, 25 | remove.spaces = TRUE 26 | ) 27 | } 28 | \arguments{ 29 | \item{data}{Matrix with correlation coefficients as returned by the 30 | \code{\link{cor}}-function, or a \code{data.frame} of variables where 31 | correlations between columns should be computed.} 32 | 33 | \item{na.deletion}{Indicates how missing values are treated. May be either 34 | \code{"listwise"} (default) or \code{"pairwise"}. May be 35 | abbreviated.} 36 | 37 | \item{corr.method}{Indicates the correlation computation method. May be one of 38 | \code{"pearson"} (default), \code{"spearman"} or \code{"kendall"}. 39 | May be abbreviated.} 40 | 41 | \item{title}{String, will be used as table caption.} 42 | 43 | \item{var.labels}{Character vector with variable names, which will be used 44 | to label variables in the output.} 45 | 46 | \item{wrap.labels}{Numeric, determines how many chars of the value, variable 47 | or axis labels are displayed in one line and when a line break is inserted.} 48 | 49 | \item{show.p}{Logical, if \code{TRUE}, p-values are also printed.} 50 | 51 | \item{p.numeric}{Logical, if \code{TRUE}, the p-values are printed 52 | as numbers. If \code{FALSE} (default), asterisks are used.} 53 | 54 | \item{fade.ns}{Logical, if \code{TRUE} (default), non-significant correlation-values 55 | appear faded (by using a lighter grey text color). See 'Note'.} 56 | 57 | \item{val.rm}{Specify a number between 0 and 1 to suppress the output of correlation values 58 | that are smaller than \code{val.rm}. The absolute correlation values are used, so 59 | a correlation value of \code{-.5} would be greater than \code{val.rm = .4} and thus not be 60 | omitted. By default, this argument is \code{NULL}, hence all values are shown in the table. 61 | If a correlation value is below the specified value of \code{val.rm}, it is still printed to 62 | the HTML table, but made "invisible" with white foreground color. You can use the \code{CSS} 63 | argument (\code{"css.valueremove"}) to change color and appearance of those correlation value that are smaller than 64 | the limit specified by \code{val.rm}.} 65 | 66 | \item{digits}{Amount of decimals for estimates} 67 | 68 | \item{triangle}{Indicates whether only the upper right (use \code{"upper"}), lower left (use \code{"lower"}) 69 | or both (use \code{"both"}) triangles of the correlation table is filled with values. Default 70 | is \code{"both"}. You can specifiy the inital letter only.} 71 | 72 | \item{string.diag}{A vector with string values of the same length as \code{ncol(data)} (number of 73 | correlated items) that can be used to display content in the diagonal cells 74 | where row and column item are identical (i.e. the "self-correlation"). By defauilt, 75 | this argument is \code{NULL} and the diagnal cells are empty.} 76 | 77 | \item{CSS}{A \code{\link{list}} with user-defined style-sheet-definitions, 78 | according to the \href{https://www.w3.org/Style/CSS/}{official CSS syntax}. 79 | See 'Details' or \href{https://strengejacke.github.io/sjPlot/articles/table_css.html}{this package-vignette}.} 80 | 81 | \item{encoding}{Character vector, indicating the charset encoding used 82 | for variable and value labels. Default is \code{"UTF-8"}. For Windows 83 | Systems, \code{encoding = "Windows-1252"} might be necessary for proper 84 | display of special characters.} 85 | 86 | \item{file}{Destination file, if the output should be saved as file. 87 | If \code{NULL} (default), the output will be saved as temporary file and 88 | opened either in the IDE's viewer pane or the default web browser.} 89 | 90 | \item{use.viewer}{Logical, if \code{TRUE}, the HTML table is shown in the IDE's 91 | viewer pane. If \code{FALSE} or no viewer available, the HTML table is 92 | opened in a web browser.} 93 | 94 | \item{remove.spaces}{Logical, if \code{TRUE}, leading spaces are removed from all lines in the final string 95 | that contains the html-data. Use this, if you want to remove parantheses for html-tags. The html-source 96 | may look less pretty, but it may help when exporting html-tables to office tools.} 97 | } 98 | \value{ 99 | Invisibly returns 100 | \itemize{ 101 | \item the web page style sheet (\code{page.style}), 102 | \item the web page content (\code{page.content}), 103 | \item the complete html-output (\code{page.complete}) and 104 | \item the html-table with inline-css for use with knitr (\code{knitr}) 105 | } 106 | for further use. 107 | } 108 | \description{ 109 | Shows the results of a computed correlation as HTML table. Requires either 110 | a \code{\link{data.frame}} or a matrix with correlation coefficients 111 | as returned by the \code{\link{cor}}-function. 112 | } 113 | \note{ 114 | If \code{data} is a matrix with correlation coefficients as returned by 115 | the \code{\link{cor}}-function, p-values can't be computed. 116 | Thus, \code{show.p}, \code{p.numeric} and \code{fade.ns} 117 | only have an effect if \code{data} is a \code{\link{data.frame}}. 118 | } 119 | \examples{ 120 | \dontrun{ 121 | if (interactive()) { 122 | # Data from the EUROFAMCARE sample dataset 123 | library(sjmisc) 124 | data(efc) 125 | 126 | # retrieve variable and value labels 127 | varlabs <- get_label(efc) 128 | 129 | # recveive first item of COPE-index scale 130 | start <- which(colnames(efc) == "c83cop2") 131 | # recveive last item of COPE-index scale 132 | end <- which(colnames(efc) == "c88cop7") 133 | 134 | # create data frame with COPE-index scale 135 | mydf <- data.frame(efc[, c(start:end)]) 136 | colnames(mydf) <- varlabs[c(start:end)] 137 | 138 | # we have high correlations here, because all items 139 | # belong to one factor. 140 | tab_corr(mydf, p.numeric = TRUE) 141 | 142 | # auto-detection of labels, only lower triangle 143 | tab_corr(efc[, c(start:end)], triangle = "lower") 144 | 145 | # auto-detection of labels, only lower triangle, all correlation 146 | # values smaller than 0.3 are not shown in the table 147 | tab_corr(efc[, c(start:end)], triangle = "lower", val.rm = 0.3) 148 | 149 | # auto-detection of labels, only lower triangle, all correlation 150 | # values smaller than 0.3 are printed in blue 151 | tab_corr(efc[, c(start:end)], triangle = "lower",val.rm = 0.3, 152 | CSS = list(css.valueremove = 'color:blue;')) 153 | }} 154 | } 155 | -------------------------------------------------------------------------------- /man/tab_df.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/html_print.R 3 | \name{tab_df} 4 | \alias{tab_df} 5 | \alias{tab_dfs} 6 | \title{Print data frames as HTML table.} 7 | \usage{ 8 | tab_df( 9 | x, 10 | title = NULL, 11 | footnote = NULL, 12 | col.header = NULL, 13 | show.type = FALSE, 14 | show.rownames = FALSE, 15 | show.footnote = FALSE, 16 | alternate.rows = FALSE, 17 | sort.column = NULL, 18 | digits = 2, 19 | encoding = "UTF-8", 20 | CSS = NULL, 21 | file = NULL, 22 | use.viewer = TRUE, 23 | ... 24 | ) 25 | 26 | tab_dfs( 27 | x, 28 | titles = NULL, 29 | footnotes = NULL, 30 | col.header = NULL, 31 | show.type = FALSE, 32 | show.rownames = FALSE, 33 | show.footnote = FALSE, 34 | alternate.rows = FALSE, 35 | sort.column = NULL, 36 | digits = 2, 37 | encoding = "UTF-8", 38 | CSS = NULL, 39 | file = NULL, 40 | use.viewer = TRUE, 41 | rnames = NULL, 42 | ... 43 | ) 44 | } 45 | \arguments{ 46 | \item{x}{For \code{tab_df()}, a data frame; and for \code{tab_dfs()}, a 47 | list of data frames.} 48 | 49 | \item{title, titles, footnote, footnotes}{Character vector with table 50 | caption(s) resp. footnote(s). For \code{tab_df()}, must be a character 51 | of length 1; for \code{tab_dfs()}, a character vector of same length as 52 | \code{x} (i.e. one title or footnote per data frame).} 53 | 54 | \item{col.header}{Character vector with elements used as column header for 55 | the table. If \code{NULL}, column names from \code{x} are used as 56 | column header.} 57 | 58 | \item{show.type}{Logical, if \code{TRUE}, adds information about the 59 | variable type to the variable column.} 60 | 61 | \item{show.rownames}{Logical, if \code{TRUE}, adds a column with the 62 | data frame's rowname to the table output.} 63 | 64 | \item{show.footnote}{Logical, if \code{TRUE},adds a summary footnote below 65 | the table. For \code{tab_df()}, specify the string in \code{footnote}, 66 | for \code{tab_dfs()} provide a character vector in \code{footnotes}.} 67 | 68 | \item{alternate.rows}{Logical, if \code{TRUE}, rows are printed in 69 | alternatig colors (white and light grey by default).} 70 | 71 | \item{sort.column}{Numeric vector, indicating the index of the column 72 | that should sorted. by default, the column is sorted in ascending order. 73 | Use negative index for descending order, for instance, 74 | \code{sort.column = -3} would sort the third column in descending order. 75 | Note that the first column with rownames is not counted.} 76 | 77 | \item{digits}{Numeric, amount of digits after decimal point when rounding 78 | values.} 79 | 80 | \item{encoding}{Character vector, indicating the charset encoding used 81 | for variable and value labels. Default is \code{"UTF-8"}. For Windows 82 | Systems, \code{encoding = "Windows-1252"} might be necessary for proper 83 | display of special characters.} 84 | 85 | \item{CSS}{A \code{\link{list}} with user-defined style-sheet-definitions, 86 | according to the \href{https://www.w3.org/Style/CSS/}{official CSS syntax}. 87 | See 'Details' or \href{https://strengejacke.github.io/sjPlot/articles/table_css.html}{this package-vignette}.} 88 | 89 | \item{file}{Destination file, if the output should be saved as file. 90 | If \code{NULL} (default), the output will be saved as temporary file and 91 | opened either in the IDE's viewer pane or the default web browser.} 92 | 93 | \item{use.viewer}{Logical, if \code{TRUE}, the HTML table is shown in the IDE's 94 | viewer pane. If \code{FALSE} or no viewer available, the HTML table is 95 | opened in a web browser.} 96 | 97 | \item{...}{Currently not used.} 98 | 99 | \item{rnames}{Character vector, can be used to set row names when \code{show.rownames=TRUE}.} 100 | } 101 | \value{ 102 | A list with following items: 103 | \itemize{ 104 | \item the web page style sheet (\code{page.style}), 105 | \item the HTML content of the data frame (\code{page.content}), 106 | \item the complete HTML page, including header, style sheet and body (\code{page.complete}) 107 | \item the HTML table with inline-css for use with knitr (\code{knitr}) 108 | \item the file path, if the HTML page should be saved to disk (\code{file}) 109 | } 110 | } 111 | \description{ 112 | These functions print data frames as HTML-table, showing 113 | the results in RStudio's viewer pane or in a web browser. 114 | } 115 | \details{ 116 | \strong{How do I use \code{CSS}-argument?} 117 | \cr \cr 118 | With the \code{CSS}-argument, the visual appearance of the tables 119 | can be modified. To get an overview of all style-sheet-classnames 120 | that are used in this function, see return value \code{page.style} for 121 | details. Arguments for this list have following syntax: 122 | \enumerate{ 123 | \item the class-name as argument name and 124 | \item each style-definition must end with a semicolon 125 | } 126 | You can add style information to the default styles by using a + 127 | (plus-sign) as initial character for the argument attributes. 128 | Examples: 129 | \itemize{ 130 | \item \code{table = 'border:2px solid red;'} for a solid 2-pixel table border in red. 131 | \item \code{summary = 'font-weight:bold;'} for a bold fontweight in the summary row. 132 | \item \code{lasttablerow = 'border-bottom: 1px dotted blue;'} for a blue dotted border of the last table row. 133 | \item \code{colnames = '+color:green'} to add green color formatting to column names. 134 | \item \code{arc = 'color:blue;'} for a blue text color each 2nd row. 135 | \item \code{caption = '+color:red;'} to add red font-color to the default table caption style. 136 | } 137 | See further examples in \href{https://strengejacke.github.io/sjPlot/articles/table_css.html}{this package-vignette}. 138 | } 139 | \note{ 140 | The HTML tables can either be saved as file and manually opened 141 | (use argument \code{file}) or they can be saved as temporary files and 142 | will be displayed in the RStudio Viewer pane (if working with RStudio) 143 | or opened with the default web browser. Displaying resp. opening a 144 | temporary file is the default behaviour. 145 | } 146 | \examples{ 147 | \dontrun{ 148 | data(iris) 149 | data(mtcars) 150 | tab_df(iris[1:5, ]) 151 | tab_dfs(list(iris[1:5, ], mtcars[1:5, 1:5])) 152 | 153 | # sort 2nd column ascending 154 | tab_df(iris[1:5, ], sort.column = 2) 155 | 156 | # sort 2nd column descending 157 | tab_df(iris[1:5, ], sort.column = -2)} 158 | 159 | } 160 | -------------------------------------------------------------------------------- /man/tab_fa.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tab_fa.R 3 | \name{tab_fa} 4 | \alias{tab_fa} 5 | \title{Summary of factor analysis as HTML table} 6 | \usage{ 7 | tab_fa( 8 | data, 9 | rotation = "promax", 10 | method = c("ml", "minres", "wls", "gls", "pa", "minchi", "minrank"), 11 | nmbr.fctr = NULL, 12 | fctr.load.tlrn = 0.1, 13 | sort = FALSE, 14 | title = "Factor Analysis", 15 | var.labels = NULL, 16 | wrap.labels = 40, 17 | show.cronb = TRUE, 18 | show.comm = FALSE, 19 | alternate.rows = FALSE, 20 | digits = 2, 21 | CSS = NULL, 22 | encoding = NULL, 23 | file = NULL, 24 | use.viewer = TRUE, 25 | remove.spaces = TRUE 26 | ) 27 | } 28 | \arguments{ 29 | \item{data}{A data frame that should be used to compute a PCA, or a \code{\link{prcomp}} object.} 30 | 31 | \item{rotation}{Rotation of the factor loadings. May be one of 32 | \code{"varimax", "quartimax", "promax", "oblimin", "simplimax", "cluster"} 33 | or \code{"none"}.} 34 | 35 | \item{method}{the factoring method to be used. \code{"ml"} will do a maximum likelihood factor analysis (default). 36 | \code{"minres"} will do a minimum residual (OLS), 37 | \code{"wls"} will do a weighted least squares (WLS) solution, 38 | \code{"gls"} does a generalized weighted least squares (GLS), 39 | \code{"pa"} will do the principal factor solution, 40 | \code{"minchi"} will minimize the sample size weighted chi square 41 | when treating pairwise correlations with different number of 42 | subjects per pair. \code{"minrank"} will do a minimum rank factor analysis.} 43 | 44 | \item{nmbr.fctr}{Number of factors used for calculating the rotation. By 45 | default, this value is \code{NULL} and the amount of factors is 46 | calculated according to the Kaiser-criteria.} 47 | 48 | \item{fctr.load.tlrn}{Specifies the minimum difference a variable needs to have between 49 | factor loadings (components) in order to indicate a clear loading on just one factor and not 50 | diffusing over all factors. For instance, a variable with 0.8, 0.82 and 0.84 factor loading 51 | on 3 possible factors can not be clearly assigned to just one factor and thus would be removed 52 | from the principal component analysis. By default, the minimum difference of loading values 53 | between the highest and 2nd highest factor should be 0.1} 54 | 55 | \item{sort}{logical, if \code{TRUE}, sort the loadings for each factors 56 | (items will be sorted in terms of their greatest loading, in descending 57 | order)} 58 | 59 | \item{title}{String, will be used as table caption.} 60 | 61 | \item{var.labels}{Character vector with variable names, which will be used 62 | to label variables in the output.} 63 | 64 | \item{wrap.labels}{Numeric, determines how many chars of the value, variable 65 | or axis labels are displayed in one line and when a line break is inserted.} 66 | 67 | \item{show.cronb}{Logical, if \code{TRUE} (default), the cronbach's alpha value for each factor scale will be calculated, 68 | i.e. all variables with the highest loading for a factor are taken for the 69 | reliability test. The result is an alpha value for each factor dimension. 70 | Only applies when \code{data} is a data frame.} 71 | 72 | \item{show.comm}{Logical, if \code{TRUE}, show the communality column in the table.} 73 | 74 | \item{alternate.rows}{Logical, if \code{TRUE}, rows are printed in 75 | alternatig colors (white and light grey by default).} 76 | 77 | \item{digits}{Amount of decimals for estimates} 78 | 79 | \item{CSS}{A \code{\link{list}} with user-defined style-sheet-definitions, 80 | according to the \href{https://www.w3.org/Style/CSS/}{official CSS syntax}. 81 | See 'Details' or \href{https://strengejacke.github.io/sjPlot/articles/table_css.html}{this package-vignette}.} 82 | 83 | \item{encoding}{Character vector, indicating the charset encoding used 84 | for variable and value labels. Default is \code{"UTF-8"}. For Windows 85 | Systems, \code{encoding = "Windows-1252"} might be necessary for proper 86 | display of special characters.} 87 | 88 | \item{file}{Destination file, if the output should be saved as file. 89 | If \code{NULL} (default), the output will be saved as temporary file and 90 | opened either in the IDE's viewer pane or the default web browser.} 91 | 92 | \item{use.viewer}{Logical, if \code{TRUE}, the HTML table is shown in the IDE's 93 | viewer pane. If \code{FALSE} or no viewer available, the HTML table is 94 | opened in a web browser.} 95 | 96 | \item{remove.spaces}{Logical, if \code{TRUE}, leading spaces are removed from all lines in the final string 97 | that contains the html-data. Use this, if you want to remove parantheses for html-tags. The html-source 98 | may look less pretty, but it may help when exporting html-tables to office tools.} 99 | } 100 | \value{ 101 | Invisibly returns 102 | \itemize{ 103 | \item the web page style sheet (\code{page.style}), 104 | \item the web page content (\code{page.content}), 105 | \item the complete html-output (\code{page.complete}), 106 | \item the html-table with inline-css for use with knitr (\code{knitr}), 107 | \item the \code{factor.index}, i.e. the column index of each variable with the highest factor loading for each factor and 108 | \item the \code{removed.items}, i.e. which variables have been removed because they were outside of the \code{fctr.load.tlrn}'s range. 109 | } 110 | for further use. 111 | } 112 | \description{ 113 | Performs a factor analysis on a data frame or matrix 114 | and displays the factors as HTML 115 | table, or saves them as file. \cr \cr In case a data frame is used as 116 | parameter, the Cronbach's Alpha value for each factor scale will be calculated, 117 | i.e. all variables with the highest loading for a factor are taken for the 118 | reliability test. The result is an alpha value for each factor dimension. 119 | } 120 | \note{ 121 | This method for factor analysis relies on the functions 122 | \code{\link[psych]{fa}} and \code{\link[psych]{fa.parallel}} from the psych package. 123 | } 124 | \examples{ 125 | \dontrun{ 126 | # Data from the EUROFAMCARE sample dataset 127 | library(sjmisc) 128 | library(GPArotation) 129 | data(efc) 130 | 131 | # recveive first item of COPE-index scale 132 | start <- which(colnames(efc) == "c82cop1") 133 | # recveive last item of COPE-index scale 134 | end <- which(colnames(efc) == "c90cop9") 135 | # auto-detection of labels 136 | if (interactive()) { 137 | tab_fa(efc[, start:end]) 138 | }} 139 | } 140 | -------------------------------------------------------------------------------- /man/tab_pca.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tab_pca.R 3 | \name{tab_pca} 4 | \alias{tab_pca} 5 | \title{Summary of principal component analysis as HTML table} 6 | \usage{ 7 | tab_pca( 8 | data, 9 | rotation = c("varimax", "quartimax", "promax", "oblimin", "simplimax", "cluster", 10 | "none"), 11 | nmbr.fctr = NULL, 12 | fctr.load.tlrn = 0.1, 13 | title = "Principal Component Analysis", 14 | var.labels = NULL, 15 | wrap.labels = 40, 16 | show.cronb = TRUE, 17 | show.msa = FALSE, 18 | show.var = FALSE, 19 | alternate.rows = FALSE, 20 | digits = 2, 21 | string.pov = "Proportion of Variance", 22 | string.cpov = "Cumulative Proportion", 23 | CSS = NULL, 24 | encoding = NULL, 25 | file = NULL, 26 | use.viewer = TRUE, 27 | remove.spaces = TRUE 28 | ) 29 | } 30 | \arguments{ 31 | \item{data}{A data frame that should be used to compute a PCA, or a \code{\link{prcomp}} object.} 32 | 33 | \item{rotation}{Rotation of the factor loadings. May be one of 34 | \code{"varimax", "quartimax", "promax", "oblimin", "simplimax", "cluster"} 35 | or \code{"none"}.} 36 | 37 | \item{nmbr.fctr}{Number of factors used for calculating the rotation. By 38 | default, this value is \code{NULL} and the amount of factors is 39 | calculated according to the Kaiser-criteria.} 40 | 41 | \item{fctr.load.tlrn}{Specifies the minimum difference a variable needs to have between 42 | factor loadings (components) in order to indicate a clear loading on just one factor and not 43 | diffusing over all factors. For instance, a variable with 0.8, 0.82 and 0.84 factor loading 44 | on 3 possible factors can not be clearly assigned to just one factor and thus would be removed 45 | from the principal component analysis. By default, the minimum difference of loading values 46 | between the highest and 2nd highest factor should be 0.1} 47 | 48 | \item{title}{String, will be used as table caption.} 49 | 50 | \item{var.labels}{Character vector with variable names, which will be used 51 | to label variables in the output.} 52 | 53 | \item{wrap.labels}{Numeric, determines how many chars of the value, variable 54 | or axis labels are displayed in one line and when a line break is inserted.} 55 | 56 | \item{show.cronb}{Logical, if \code{TRUE} (default), the cronbach's alpha value for each factor scale will be calculated, 57 | i.e. all variables with the highest loading for a factor are taken for the 58 | reliability test. The result is an alpha value for each factor dimension. 59 | Only applies when \code{data} is a data frame.} 60 | 61 | \item{show.msa}{Logical, if \code{TRUE}, shows an additional column with the measure of sampling adequacy according 62 | dor each component.} 63 | 64 | \item{show.var}{Logical, if \code{TRUE}, the proportions of variances for each component as well as cumulative 65 | variance are shown in the table footer.} 66 | 67 | \item{alternate.rows}{Logical, if \code{TRUE}, rows are printed in 68 | alternatig colors (white and light grey by default).} 69 | 70 | \item{digits}{Amount of decimals for estimates} 71 | 72 | \item{string.pov}{String for the table row that contains the proportions of variances. By default, 73 | \emph{"Proportion of Variance"} will be used.} 74 | 75 | \item{string.cpov}{String for the table row that contains the cumulative variances. By default, 76 | \emph{"Cumulative Proportion"} will be used.} 77 | 78 | \item{CSS}{A \code{\link{list}} with user-defined style-sheet-definitions, 79 | according to the \href{https://www.w3.org/Style/CSS/}{official CSS syntax}. 80 | See 'Details' or \href{https://strengejacke.github.io/sjPlot/articles/table_css.html}{this package-vignette}.} 81 | 82 | \item{encoding}{Character vector, indicating the charset encoding used 83 | for variable and value labels. Default is \code{"UTF-8"}. For Windows 84 | Systems, \code{encoding = "Windows-1252"} might be necessary for proper 85 | display of special characters.} 86 | 87 | \item{file}{Destination file, if the output should be saved as file. 88 | If \code{NULL} (default), the output will be saved as temporary file and 89 | opened either in the IDE's viewer pane or the default web browser.} 90 | 91 | \item{use.viewer}{Logical, if \code{TRUE}, the HTML table is shown in the IDE's 92 | viewer pane. If \code{FALSE} or no viewer available, the HTML table is 93 | opened in a web browser.} 94 | 95 | \item{remove.spaces}{Logical, if \code{TRUE}, leading spaces are removed from all lines in the final string 96 | that contains the html-data. Use this, if you want to remove parantheses for html-tags. The html-source 97 | may look less pretty, but it may help when exporting html-tables to office tools.} 98 | } 99 | \value{ 100 | Invisibly returns 101 | \itemize{ 102 | \item the web page style sheet (\code{page.style}), 103 | \item the web page content (\code{page.content}), 104 | \item the complete html-output (\code{page.complete}), 105 | \item the html-table with inline-css for use with knitr (\code{knitr}), 106 | \item the \code{factor.index}, i.e. the column index of each variable with the highest factor loading for each factor and 107 | \item the \code{removed.items}, i.e. which variables have been removed because they were outside of the \code{fctr.load.tlrn}'s range. 108 | } 109 | for further use. 110 | } 111 | \description{ 112 | Performes a principle component analysis on a data frame or matrix 113 | (with varimax or oblimin rotation) and displays the factor solution as HTML 114 | table, or saves them as file. \cr \cr In case a data frame is used as 115 | parameter, the Cronbach's Alpha value for each factor scale will be calculated, 116 | i.e. all variables with the highest loading for a factor are taken for the 117 | reliability test. The result is an alpha value for each factor dimension. 118 | } 119 | \examples{ 120 | \dontrun{ 121 | # Data from the EUROFAMCARE sample dataset 122 | library(sjmisc) 123 | data(efc) 124 | 125 | # recveive first item of COPE-index scale 126 | start <- which(colnames(efc) == "c82cop1") 127 | # recveive last item of COPE-index scale 128 | end <- which(colnames(efc) == "c90cop9") 129 | # auto-detection of labels 130 | if (interactive()) { 131 | tab_pca(efc[, start:end]) 132 | }} 133 | } 134 | -------------------------------------------------------------------------------- /man/view_df.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/view_df.R 3 | \name{view_df} 4 | \alias{view_df} 5 | \title{View structure of labelled data frames} 6 | \usage{ 7 | view_df( 8 | x, 9 | weight.by = NULL, 10 | alternate.rows = TRUE, 11 | show.id = TRUE, 12 | show.type = FALSE, 13 | show.values = TRUE, 14 | show.string.values = FALSE, 15 | show.labels = TRUE, 16 | show.frq = FALSE, 17 | show.prc = FALSE, 18 | show.wtd.frq = FALSE, 19 | show.wtd.prc = FALSE, 20 | show.na = FALSE, 21 | max.len = 15, 22 | sort.by.name = FALSE, 23 | wrap.labels = 50, 24 | verbose = FALSE, 25 | CSS = NULL, 26 | encoding = NULL, 27 | file = NULL, 28 | use.viewer = TRUE, 29 | remove.spaces = TRUE 30 | ) 31 | } 32 | \arguments{ 33 | \item{x}{A (labelled) data frame, imported by \code{\link[sjlabelled]{read_spss}}, 34 | \code{\link[sjlabelled]{read_sas}} or \code{\link[sjlabelled]{read_stata}} function, 35 | or any similar labelled data frame (see \code{\link[sjlabelled]{set_label}} 36 | and \code{\link[sjlabelled]{set_labels}}).} 37 | 38 | \item{weight.by}{Name of variable in \code{x} that indicated the vector of 39 | weights that will be applied to weight all observations. Default is 40 | \code{NULL}, so no weights are used.} 41 | 42 | \item{alternate.rows}{Logical, if \code{TRUE}, rows are printed in 43 | alternatig colors (white and light grey by default).} 44 | 45 | \item{show.id}{Logical, if \code{TRUE} (default), the variable ID is shown in 46 | the first column.} 47 | 48 | \item{show.type}{Logical, if \code{TRUE}, adds information about the 49 | variable type to the variable column.} 50 | 51 | \item{show.values}{Logical, if \code{TRUE} (default), the variable values 52 | are shown as additional column.} 53 | 54 | \item{show.string.values}{Logical, if \code{TRUE}, elements of character vectors 55 | are also shown. By default, these are omitted due to possibly overlengthy 56 | tables.} 57 | 58 | \item{show.labels}{Logical, if \code{TRUE} (default), the value labels are 59 | shown as additional column.} 60 | 61 | \item{show.frq}{Logical, if \code{TRUE}, an additional column with 62 | frequencies for each variable is shown.} 63 | 64 | \item{show.prc}{Logical, if \code{TRUE}, an additional column with percentage 65 | of frequencies for each variable is shown.} 66 | 67 | \item{show.wtd.frq}{Logical, if \code{TRUE}, an additional column with weighted 68 | frequencies for each variable is shown. Weights strem from \code{weight.by}.} 69 | 70 | \item{show.wtd.prc}{Logical, if \code{TRUE}, an additional column with weighted 71 | percentage of frequencies for each variable is shown. Weights strem from 72 | \code{weight.by}.} 73 | 74 | \item{show.na}{logical, if \code{TRUE}, \code{\link{NA}}'s (missing values) 75 | are added to the output.} 76 | 77 | \item{max.len}{Numeric, indicates how many values and value labels per variable 78 | are shown. Useful for variables with many different values, where the output 79 | can be truncated.} 80 | 81 | \item{sort.by.name}{Logical, if \code{TRUE}, rows are sorted according to the 82 | variable names. By default, rows (variables) are ordered according to their 83 | order in the data frame.} 84 | 85 | \item{wrap.labels}{Numeric, determines how many chars of the value, variable 86 | or axis labels are displayed in one line and when a line break is inserted.} 87 | 88 | \item{verbose}{Logical, if \code{TRUE}, a progress bar is displayed 89 | while creating the output.} 90 | 91 | \item{CSS}{A \code{\link{list}} with user-defined style-sheet-definitions, 92 | according to the \href{https://www.w3.org/Style/CSS/}{official CSS syntax}. 93 | See 'Details' or \href{https://strengejacke.github.io/sjPlot/articles/table_css.html}{this package-vignette}.} 94 | 95 | \item{encoding}{Character vector, indicating the charset encoding used 96 | for variable and value labels. Default is \code{"UTF-8"}. For Windows 97 | Systems, \code{encoding = "Windows-1252"} might be necessary for proper 98 | display of special characters.} 99 | 100 | \item{file}{Destination file, if the output should be saved as file. 101 | If \code{NULL} (default), the output will be saved as temporary file and 102 | opened either in the IDE's viewer pane or the default web browser.} 103 | 104 | \item{use.viewer}{Logical, if \code{TRUE}, the HTML table is shown in the IDE's 105 | viewer pane. If \code{FALSE} or no viewer available, the HTML table is 106 | opened in a web browser.} 107 | 108 | \item{remove.spaces}{Logical, if \code{TRUE}, leading spaces are removed from all lines in the final string 109 | that contains the html-data. Use this, if you want to remove parantheses for html-tags. The html-source 110 | may look less pretty, but it may help when exporting html-tables to office tools.} 111 | } 112 | \value{ 113 | Invisibly returns 114 | \itemize{ 115 | \item the web page style sheet (\code{page.style}), 116 | \item the web page content (\code{page.content}), 117 | \item the complete html-output (\code{page.complete}) and 118 | \item the html-table with inline-css for use with knitr (\code{knitr}) 119 | } 120 | for further use. 121 | } 122 | \description{ 123 | Save (or show) content of an imported SPSS, SAS or Stata data file, 124 | or any similar labelled \code{data.frame}, as HTML table. 125 | This quick overview shows variable ID number, name, label, 126 | type and associated value labels. The result can be 127 | considered as "codeplan" of the data frame. 128 | } 129 | \examples{ 130 | \dontrun{ 131 | # init dataset 132 | data(efc) 133 | 134 | # view variables 135 | view_df(efc) 136 | 137 | # view variables w/o values and value labels 138 | view_df(efc, show.values = FALSE, show.labels = FALSE) 139 | 140 | # view variables including variable typed, orderd by name 141 | view_df(efc, sort.by.name = TRUE, show.type = TRUE) 142 | 143 | # User defined style sheet 144 | view_df(efc, 145 | CSS = list(css.table = "border: 2px solid;", 146 | css.tdata = "border: 1px solid;", 147 | css.arc = "color:blue;"))} 148 | 149 | } 150 | -------------------------------------------------------------------------------- /sjPlot.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "launch": { 8 | "version": "0.2.0", 9 | "configurations": [ 10 | { 11 | "type": "R-Debugger", 12 | "name": "Launch R-Workspace", 13 | "request": "launch", 14 | "debugMode": "workspace", 15 | "workingDirectory": "" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(sjPlot) 3 | 4 | if (length(strsplit(packageDescription("sjPlot")$Version, "\\.")[[1]]) > 3) { 5 | Sys.setenv("RunAllsjPlotTests" = "yes") 6 | } 7 | 8 | test_check("sjPlot") 9 | -------------------------------------------------------------------------------- /tests/testthat/test-plot_grpfrq.R: -------------------------------------------------------------------------------- 1 | if (suppressWarnings( 2 | require("testthat") && 3 | require("sjlabelled") && 4 | require("haven") && 5 | require("sjPlot") 6 | )) { 7 | 8 | # glm, logistic regression ---- 9 | data(efc) 10 | efc$gewicht <- rnorm(nrow(efc), 1, .2) 11 | 12 | test_that("plot_grpfrq", { 13 | p <- plot_grpfrq(efc$e17age, efc$e16sex) 14 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "dot") 15 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "line") 16 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "boxplot") 17 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "violin") 18 | 19 | p <- plot_grpfrq(efc$e17age, efc$e16sex, bar.pos = "stack") 20 | 21 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "boxplot", intr.var = efc$c172code) 22 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "violin", intr.var = efc$c172code) 23 | 24 | p <- plot_grpfrq(efc$e17age, efc$e16sex, show.values = FALSE) 25 | p <- plot_grpfrq(efc$e17age, efc$e16sex, show.values = FALSE, show.n = TRUE) 26 | 27 | p <- plot_grpfrq(efc$e17age, efc$e16sex, show.values = TRUE, show.n = TRUE) 28 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "dot", show.values = TRUE, show.n = TRUE) 29 | p <- plot_grpfrq(efc$e17age, efc$e16sex, show.values = TRUE, show.n = TRUE, show.prc = TRUE) 30 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "dot", show.values = TRUE, show.n = TRUE, show.prc = TRUE) 31 | 32 | p <- plot_grpfrq(efc$e17age, efc$e16sex, show.grpcnt = TRUE) 33 | expect_message(p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "boxplot", show.grpcnt = TRUE)) 34 | expect_message(p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "boxplot", intr.var = efc$c172code, show.grpcnt = TRUE)) 35 | 36 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "bar", show.grpcnt = TRUE) 37 | 38 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "dot") 39 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "dot", show.ci = T) 40 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "line", show.ci = T) 41 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "boxplot", show.ci = T) 42 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "violin", show.ci = T) 43 | 44 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, weight.by = efc$gewicht) 45 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "dot", weight.by = efc$gewicht) 46 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "line", weight.by = efc$gewicht) 47 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "boxplot", weight.by = efc$gewicht) 48 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "violin", weight.by = efc$gewicht) 49 | 50 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, legend.title = "Geschlecht", legend.labels = c("M", "W"), axis.titles = "Dependency", axis.labels = c("gar nicht", "leicht", "mittel", "schwer")) 51 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "dot", legend.title = "Geschlecht", legend.labels = c("M", "W"), axis.titles = "Dependency", axis.labels = c("gar nicht", "leicht", "mittel", "schwer")) 52 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "line", legend.title = "Geschlecht", legend.labels = c("M", "W"), axis.titles = "Dependency", axis.labels = c("gar nicht", "leicht", "mittel", "schwer")) 53 | p <- plot_grpfrq(efc$e42dep, efc$e16sex, type = "boxplot", legend.title = "Geschlecht", legend.labels = c("M", "W"), axis.titles = "Dependency", axis.labels = c("A", "B")) 54 | p <- plot_grpfrq(efc$e17age, efc$e16sex, type = "violin", legend.title = "Geschlecht", legend.labels = c("M", "W"), axis.titles = "Dependency", axis.labels = c("A", "B")) 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /tests/testthat/test-plot_model_std.R: -------------------------------------------------------------------------------- 1 | .runThisTest <- Sys.getenv("RunAllsjPlotTests") == "yes" 2 | 3 | if (suppressWarnings( 4 | require("testthat") && 5 | require("sjPlot") && 6 | require("sjmisc") && 7 | require("sjlabelled") && 8 | require("haven") && 9 | require("lme4") 10 | )) { 11 | context("sjPlot, tab_model type std") 12 | 13 | data(sleepstudy) 14 | data(iris) 15 | data(efc) 16 | 17 | efc <- to_factor(efc, e42dep, c172code, c161sex) 18 | 19 | m1 <- lmer(Reaction ~ Days + (1 + Days | Subject), data = sleepstudy, REML = F) 20 | m2 <- lmer(Sepal.Length ~ Sepal.Width + Petal.Length + (1 | Species), data = iris) 21 | m3 <- lm(neg_c_7 ~ e42dep + barthtot + c161sex, data = efc) 22 | 23 | test_that("plot_model", { 24 | p <- plot_model(m1) 25 | p <- plot_model(m2) 26 | p <- plot_model(m3) 27 | 28 | p <- plot_model(m1, type = "slope") 29 | p <- plot_model(m2, type = "slope") 30 | p <- plot_model(m3, type = "slope") 31 | 32 | p <- plot_model(m1, type = "resid") 33 | p <- plot_model(m2, type = "resid") 34 | p <- plot_model(m3, type = "resid") 35 | }) 36 | 37 | 38 | test_that("plot_model, std", { 39 | p <- plot_model(m1, type = "std") 40 | p <- plot_model(m1, type = "std2") 41 | p <- plot_model(m2, type = "std") 42 | p <- plot_model(m2, type = "std2") 43 | p <- plot_model(m3, type = "std") 44 | p <- plot_model(m3, type = "std2") 45 | }) 46 | 47 | 48 | if (.runThisTest) { 49 | 50 | if (suppressWarnings( 51 | require("testthat") && 52 | require("rstanarm") && 53 | require("sjPlot") && 54 | require("lme4") 55 | )) { 56 | 57 | # fit linear model 58 | data(sleepstudy) 59 | sleepstudy$age <- round(runif(nrow(sleepstudy), min = 20, max = 60)) 60 | sleepstudy$Rdicho <- dicho(sleepstudy$Reaction) 61 | 62 | m1 <- stan_glmer( 63 | Reaction ~ Days + age + (1 | Subject), 64 | data = sleepstudy, QR = TRUE, 65 | # this next line is only to keep the example small in size! 66 | chains = 2, cores = 1, seed = 12345, iter = 500 67 | ) 68 | 69 | m2 <- stan_glmer( 70 | Rdicho ~ Days + age + (1 | Subject), 71 | data = sleepstudy, QR = TRUE, 72 | family = binomial, 73 | chains = 2, iter = 500 74 | ) 75 | 76 | test_that("plot_model, rstan", { 77 | p <- plot_model(m1) 78 | p <- plot_model(m2) 79 | p <- plot_model(m1, bpe = "mean") 80 | p <- plot_model(m2, bpe = "mean") 81 | p <- plot_model(m1, bpe = "mean", bpe.style = "dot") 82 | p <- plot_model(m2, bpe = "mean", bpe.style = "dot") 83 | p <- plot_model(m1, bpe = "mean", bpe.style = "line", bpe.color = "green") 84 | p <- plot_model(m2, bpe = "mean", bpe.style = "line", bpe.color = "green") 85 | p <- plot_model(m1, bpe = "mean", bpe.style = "line", bpe.color = "green", prob.inner = .4, prob.outer = .8) 86 | p <- plot_model(m2, bpe = "mean", bpe.style = "line", bpe.color = "green", prob.inner = .4, prob.outer = .8) 87 | p <- plot_model(m1, bpe = "mean", bpe.style = "line", bpe.color = "green", prob.inner = .4, prob.outer = .8, size.inner = .5) 88 | p <- plot_model(m2, bpe = "mean", bpe.style = "line", bpe.color = "green", prob.inner = .4, prob.outer = .8, size.inner = .5) 89 | }) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/testthat/test-tab_model.R: -------------------------------------------------------------------------------- 1 | .runThisTest <- Sys.getenv("RunAllsjPlotTests") == "yes" 2 | 3 | if (suppressWarnings( 4 | require("testthat") && 5 | require("sjPlot") && 6 | require("sjlabelled") && 7 | require("haven") && 8 | require("sjmisc") && 9 | require("lme4") && 10 | require("glmmTMB") && 11 | interactive() 12 | )) { 13 | 14 | data(sleepstudy) 15 | data(Salamanders) 16 | data(iris) 17 | data(efc) 18 | 19 | efc <- to_factor(efc, e42dep, c172code, c161sex) 20 | 21 | m1 <- lmer(Reaction ~ Days + (1 + Days | Subject), data = sleepstudy, REML = F) 22 | m2 <- lmer(Sepal.Length ~ Sepal.Width + Petal.Length + (1 | Species), data = iris) 23 | m3 <- lm(neg_c_7 ~ e42dep + barthtot + c161sex, data = efc) 24 | 25 | m4 <- glmmTMB( 26 | count ~ spp + mined + (1 | site), 27 | ziformula = ~ spp + mined, 28 | family = truncated_nbinom2, 29 | Salamanders 30 | ) 31 | 32 | test_that("tab_model", { 33 | p <- tab_model(m1, m2, m3) 34 | }) 35 | 36 | test_that("tab_model", { 37 | tab_model(m1, m2, m3, m4) 38 | }) 39 | 40 | test_that("tab_model, check shows", { 41 | p <- tab_model(m1, m2, m3, show.intercept = FALSE, show.fstat = TRUE, show.se = TRUE) 42 | p <- tab_model(m1, m2, m3, show.intercept = FALSE, show.fstat = TRUE, show.se = TRUE, show.ci = F, show.df = TRUE, p.val = "kr") 43 | }) 44 | 45 | test_that("tab_model, check terms", { 46 | p <- tab_model(m1, m2, m3, show.intercept = FALSE, show.fstat = TRUE, show.se = TRUE, terms = c("Days", "Sepal.Width", "c161sex2", "barthtot")) 47 | p <- tab_model(m1, m2, m3, show.intercept = FALSE, show.fstat = TRUE, show.se = TRUE, show.ci = F, show.df = TRUE, p.val = "kr", rm.terms = c("Days", "Sepal.Width", "c161sex2", "barthtot")) 48 | p <- tab_model(m1, m2, m3, show.intercept = FALSE, show.fstat = TRUE, show.se = TRUE, show.ci = F, show.df = TRUE, rm.terms = c("Sepal.Width", "c161sex2", "barthtot")) 49 | }) 50 | 51 | test_that("tab_model, std", { 52 | p <- tab_model(m1, show.std = "std") 53 | p <- tab_model(m1, show.std = "std2") 54 | p <- tab_model(m2, show.std = "std") 55 | p <- tab_model(m2, show.std = "std2") 56 | p <- tab_model(m1, m2, show.std = "std") 57 | p <- tab_model(m1, m2, m3, show.std = "std") 58 | p <- tab_model(m1, m2, m3, show.std = "std2") 59 | }) 60 | 61 | if (.runThisTest) { 62 | 63 | if (suppressWarnings( 64 | require("testthat") && 65 | require("rstanarm") && 66 | require("sjPlot") && 67 | require("lme4") 68 | )) { 69 | 70 | # fit linear model 71 | data(sleepstudy) 72 | sleepstudy$age <- round(runif(nrow(sleepstudy), min = 20, max = 60)) 73 | sleepstudy$Rdicho <- dicho(sleepstudy$Reaction) 74 | 75 | m1 <- stan_glmer( 76 | Reaction ~ Days + age + (1 | Subject), 77 | data = sleepstudy, QR = TRUE, 78 | # this next line is only to keep the example small in size! 79 | chains = 2, cores = 1, seed = 12345, iter = 500 80 | ) 81 | 82 | m2 <- stan_glmer( 83 | Rdicho ~ Days + age + (1 | Subject), 84 | data = sleepstudy, QR = TRUE, 85 | family = binomial, 86 | chains = 2, iter = 500 87 | ) 88 | 89 | test_that("tab_model, rstan", { 90 | p <- tab_model(m1) 91 | p <- tab_model(m2) 92 | p <- tab_model(m1, m2) 93 | p <- tab_model(m1, m2, show.ci50 = FALSE) 94 | p <- tab_model(m1, m2, col.order = c("ci.outer", "ci.inner", "est")) 95 | p <- tab_model(m1, m2, bpe = "mean") 96 | }) 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /vignettes/blackwhitefigures.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Black & White Figures for Print Journals" 3 | author: "Daniel Lüdecke" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Black & White Figures for Print Journals} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | ```{r echo = FALSE} 12 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>", dev = "png", fig.width = 7, fig.height = 5, message = FALSE, warning = FALSE) 13 | 14 | if (!requireNamespace("sjmisc", quietly = TRUE) || 15 | !requireNamespace("haven", quietly = TRUE) || 16 | !requireNamespace("ggplot2", quietly = TRUE) || 17 | !requireNamespace("sjlabelled", quietly = TRUE)) { 18 | knitr::opts_chunk$set(eval = FALSE) 19 | } 20 | ``` 21 | 22 | This document shows examples how to create b/w figures, e.g. if you don't want colored figures for print-journals. 23 | 24 | ## Barplots in grey-scaled colors 25 | 26 | There are two ways to create plots in black and white or greyscale. For bar plots, `geom.colors = "gs"` creates a plot using a greyscale (based on `scales::grey_pal()`). 27 | 28 | ```{r} 29 | library(sjPlot) 30 | library(sjmisc) 31 | library(sjlabelled) 32 | library(ggplot2) 33 | theme_set(theme_bw()) 34 | data(efc) 35 | plot_grpfrq(efc$e42dep, efc$c172code, geom.colors = "gs") 36 | ``` 37 | 38 | ## Lineplots in b/w with different linetypes 39 | 40 | Similar to barplots, lineplots - mostly from `plot_model()` - can be plotted in greyscale as well (with `colors = "gs"`). However, in most cases lines colored in greyscale are difficult to distinguish. In this case, `plot_model()` supports black & white figures with different linetypes. Use `colors = "bw"` to create a b/w-plot. 41 | 42 | ```{r} 43 | # create binrary response 44 | y <- ifelse(efc$neg_c_7 < median(na.omit(efc$neg_c_7)), 0, 1) 45 | 46 | # create data frame for fitting model 47 | df <- data.frame( 48 | y = to_factor(y), 49 | sex = to_factor(efc$c161sex), 50 | dep = to_factor(efc$e42dep), 51 | barthel = efc$barthtot, 52 | education = to_factor(efc$c172code) 53 | ) 54 | 55 | # set variable label for response 56 | set_label(df$y) <- "High Negative Impact" 57 | 58 | # fit model 59 | fit <- glm(y ~., data = df, family = binomial(link = "logit")) 60 | 61 | # plot marginal effects 62 | plot_model( 63 | fit, 64 | type = "pred", 65 | terms = c("barthel", "sex","dep"), 66 | colors = "bw", 67 | ci.lvl = NA 68 | ) 69 | ``` 70 | 71 | Different linetypes do not apply to all linetyped plots, if these usually only plot a single line - so there's no need for different linetypes, and you can just set `colors = "black"` (or `colors = "bw"`). 72 | 73 | ```{r} 74 | # plot coefficients 75 | plot_model(fit, colors = "black") 76 | ``` 77 | -------------------------------------------------------------------------------- /vignettes/plot_interactions.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Plotting Interaction Effects of Regression Models" 3 | author: "Daniel Lüdecke" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Plotting Interaction Effects of Regression Models} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r set-options, echo = FALSE} 13 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>", dev = "png", fig.width = 7, fig.height = 3.5, message = FALSE, warning = FALSE) 14 | options(width = 800, tibble.width = Inf) 15 | 16 | if (!requireNamespace("sjmisc", quietly = TRUE) || 17 | !requireNamespace("ggplot2", quietly = TRUE) || 18 | !requireNamespace("haven", quietly = TRUE) || 19 | !requireNamespace("sjlabelled", quietly = TRUE)) { 20 | knitr::opts_chunk$set(eval = FALSE) 21 | } 22 | ``` 23 | 24 | This document describes how to plot marginal effects of interaction terms from various regression models, using the `plot_model()` function. `plot_model()` is a generic plot-function, which accepts many model-objects, like `lm`, `glm`, `lme`, `lmerMod` etc. 25 | 26 | `plot_model()` allows to create various plot tyes, which can be defined via the `type`-argument. The default is `type = "fe"`, which means that fixed effects (model coefficients) are plotted. To plot marginal effects of interaction terms, call `plot_model()` with: 27 | 28 | * `type = "pred"` to plot predicted values (marginal effects) for specific model terms, including interaction terms. 29 | * `type = "eff"`, which is similar to `type = "pred"`, however, discrete predictors are held constant at their proportions (not reference level). It internally calls \code{\link[effects]{Effect}} via \code{\link[ggeffects]{ggeffect}}. 30 | * `type = "emm"`, which is similar to `type = "eff"`. It internally calls \code{\link[emmeans]{emmeans}} via \code{\link[ggeffects]{ggemmeans}}. 31 | * `type = "int"` to plot marginal effects of interaction terms in a more convenient way. 32 | 33 | `plot_model()` supports [labelled data](https://cran.r-project.org/package=sjlabelled) and automatically uses variable and value labels to annotate the plot. This works with most regression modelling functions. 34 | 35 | ***Note:** For marginal effects plots, **sjPlot** calls functions from the [**ggeffects-package**](https://strengejacke.github.io/ggeffects/). If you need more flexibility when creating marginal effects plots, consider directly using the **ggeffects**-package.* 36 | 37 | # Two-Way-Interactions 38 | 39 | _Note: To better understand the principle of plotting interaction terms, it might be helpful to read the vignette on [marginal effects](plot_marginal_effects.html) first._ 40 | 41 | To plot marginal effects of interaction terms, at least two model terms need to be specified (the terms that define the interaction) in the `terms`-argument, for which the effects are computed. To plot marginal effects for three-way-interactions, all three terms need to be specified in `terms`. 42 | 43 | A convenient way to automatically plot interactions is `type = "int"`, which scans the model formula for interaction terms and then uses these as `terms`-argument. 44 | 45 | ```{r} 46 | library(sjPlot) 47 | library(sjmisc) 48 | library(ggplot2) 49 | data(efc) 50 | theme_set(theme_sjplot()) 51 | 52 | # make categorical 53 | efc$c161sex <- to_factor(efc$c161sex) 54 | 55 | # fit model with interaction 56 | fit <- lm(neg_c_7 ~ c12hour + barthtot * c161sex, data = efc) 57 | 58 | plot_model(fit, type = "pred", terms = c("barthtot", "c161sex")) 59 | ``` 60 | 61 | For `type = "int"`, no terms need to be specified. Note that this plot type automatically uses the first interaction term in the formula for the x-axis, while the second term is used as grouping factor. Furthermore, if continuous variables are used as second term, you can specify preset-values for this term with the `mdrt.values`-argument, which are then used as grouping levels. 62 | 63 | In this example, the second term is a factor with two levels (male/female), so there is no need for choosing specific values for the moderator. 64 | 65 | ```{r} 66 | plot_model(fit, type = "int") 67 | ``` 68 | 69 | To switch the terms, in this example _barthtot_ and _c161sex_, simply switch the order of these terms on the `terms`-argument and use `type = "pred"`. 70 | 71 | ```{r} 72 | plot_model(fit, type = "pred", terms = c("c161sex", "barthtot [0, 100]")) 73 | ``` 74 | 75 | To switch the terms for plot-type `type = "int"`, you need to re-fit the model and change the formula accordingly, i.e. using _c161sex_ as first term in the interaction. 76 | 77 | ```{r} 78 | # fit model with interaction, switching terms in formula 79 | fit <- lm(neg_c_7 ~ c12hour + c161sex * barthtot, data = efc) 80 | plot_model(fit, type = "int") 81 | ``` 82 | 83 | By default, for continuous variables, the minimum and maximum values are chosen as grouping levels, which are 0 and 100 - that's why the previous two plots are identical. You have other options as well, e.g. the mean-value and +/- 1 standard deviation (as suggested by Cohen and Cohen for continuous variables and popularized by Aiken and West 1991), which can be specified using `mdrt.values`. 84 | 85 | ```{r} 86 | plot_model(fit, type = "int", mdrt.values = "meansd") 87 | ``` 88 | 89 | # Three-Way-Interactions 90 | 91 | Since the `terms`-argument accepts up to three model terms, you can also compute marginal effects for a 3-way-interaction. 92 | 93 | ```{r} 94 | # fit model with 3-way-interaction 95 | fit <- lm(neg_c_7 ~ c12hour * barthtot * c161sex, data = efc) 96 | 97 | # select only levels 30, 50 and 70 from continuous variable Barthel-Index 98 | plot_model(fit, type = "pred", terms = c("c12hour", "barthtot [30,50,70]", "c161sex")) 99 | ``` 100 | 101 | Again, `type = "int"` will automatically plot the interaction terms, however, using `mdrt.values = "minmax"` as default - in this case, the "levels" 0 and 100 from continuous variable _barthtot_ are chosen by default. 102 | 103 | ```{r} 104 | plot_model(fit, type = "int") 105 | ``` 106 | 107 | # References 108 | 109 | Aiken and West (1991). _Multiple Regression: Testing and Interpreting Interactions._ 110 | -------------------------------------------------------------------------------- /vignettes/plot_likert_scales.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Plotting Likert Scales" 3 | author: "Daniel Lüdecke" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Plotting Likert Scales} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r set-options, echo = FALSE} 13 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>", dev = "png", fig.width = 7, fig.height = 6, message = FALSE, warning = FALSE) 14 | options(width = 800, tibble.width = Inf) 15 | if (!requireNamespace("dplyr", quietly = TRUE) || 16 | !requireNamespace("sjmisc", quietly = TRUE) || 17 | !requireNamespace("haven", quietly = TRUE) || 18 | !requireNamespace("parameters", quietly = TRUE)) { 19 | knitr::opts_chunk$set(eval = FALSE) 20 | } else { 21 | knitr::opts_chunk$set(eval = TRUE) 22 | } 23 | ``` 24 | 25 | ```{r fig.height = 5.5} 26 | library(dplyr) 27 | library(sjPlot) 28 | library(sjmisc) 29 | library(parameters) 30 | data(efc) 31 | # find all variables from COPE-Index, which all have a "cop" in their 32 | # variable name, and then plot that subset as likert-plot 33 | mydf <- find_var(efc, pattern = "cop", out = "df") 34 | plot_likert(mydf) 35 | ``` 36 | 37 | ```{r} 38 | plot_likert( 39 | mydf, 40 | grid.range = c(1.2, 1.4), 41 | expand.grid = FALSE, 42 | values = "sum.outside", 43 | show.prc.sign = TRUE 44 | ) 45 | ``` 46 | 47 | ```{r} 48 | # Plot in groups 49 | plot_likert(mydf, groups = c(2, 1, 1, 1, 1, 2, 2, 2, 1)) 50 | ``` 51 | 52 | ```{r fig.height = 6.5} 53 | pca <- parameters::principal_components(mydf) 54 | groups <- parameters::closest_component(pca) 55 | plot_likert(mydf, groups = groups) 56 | ``` 57 | 58 | 59 | ```{r} 60 | plot_likert( 61 | mydf, 62 | c(rep("B", 4), rep("A", 5)), 63 | sort.groups = FALSE, 64 | grid.range = c(0.9, 1.1), 65 | geom.colors = "RdBu", 66 | rel_heights = c(6, 8), 67 | wrap.labels = 40, 68 | reverse.scale = TRUE 69 | ) 70 | ``` 71 | 72 | ```{r fig.height = 5} 73 | # control legend items 74 | six_cat_example = data.frame( 75 | matrix(sample(1:6, 600, replace = TRUE), ncol = 6) 76 | ) 77 | 78 | six_cat_example <- 79 | six_cat_example %>% 80 | dplyr::mutate_all( ~ ordered(., labels = c("+++", "++", "+", "-", "--", "---"))) 81 | 82 | # Old default 83 | plot_likert( 84 | six_cat_example, 85 | groups = c(1, 1, 1, 2, 2, 2), 86 | group.legend.options = list(nrow = 2, byrow = FALSE) 87 | ) 88 | 89 | # New default 90 | plot_likert(six_cat_example, groups = c(1, 1, 1, 2, 2, 2)) 91 | ``` 92 | -------------------------------------------------------------------------------- /vignettes/sjtitemanalysis.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Item Analysis of a Scale or an Index" 3 | author: "Daniel Lüdecke" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Item Analysis of a Scale or an Index} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r echo = FALSE} 13 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>") 14 | 15 | if (!requireNamespace("dplyr", quietly = TRUE) || 16 | !requireNamespace("sjmisc", quietly = TRUE) || 17 | !requireNamespace("parameters", quietly = TRUE) || 18 | !requireNamespace("psych", quietly = TRUE)) { 19 | knitr::opts_chunk$set(eval = FALSE) 20 | } else { 21 | knitr::opts_chunk$set(eval = TRUE) 22 | } 23 | ``` 24 | 25 | This document shows examples for using the `tab_itemscale()` function of the sjPlot package. 26 | 27 | ## Performing an item analysis of a scale or index 28 | 29 | This function performs an item analysis with certain statistics that are useful for scale or index development. Following statistics are computed for each variable (column) of a data frame: 30 | 31 | * percentage of missing values 32 | * mean value 33 | * standard deviation 34 | * skew 35 | * item difficulty 36 | * item discrimination 37 | * Cronbach's Alpha if item was removed from scale 38 | * mean (or average) inter-item-correlation 39 | 40 | Optional, following statistics can be computed as well: 41 | 42 | * kurstosis 43 | * Shapiro-Wilk Normality Test 44 | 45 | If the argument `factor.groups` is _not_ `NULL`, the data frame df will be splitted into groups, assuming that `factor.groups` indicate those columns (variables) of the data frame that belong to a certain factor (see, for instance, return value of function `tab_pca()` or `parameters::principal_components()` as example for retrieving factor groups for a scale). This is useful when you have perfomed a principal component analysis or factor analysis as first step, and now want to see whether the found factors / components represent a scale or index score. 46 | 47 | To demonstrate this function, we first need some data: 48 | 49 | ```{r, echo=FALSE, message=FALSE, warning=FALSE} 50 | library(sjPlot) 51 | library(sjmisc) 52 | library(dplyr) 53 | data(efc) 54 | # create data frame with COPE-index scale 55 | mydf <- dplyr::select(efc, contains("cop")) 56 | ``` 57 | 58 | ## Index score with one component 59 | 60 | The simplest function call is just passing the data frame as argument. In this case, the function assumes that all variables of the data frame belong to one factor only. 61 | 62 | ```{r} 63 | tab_itemscale(mydf) 64 | ``` 65 | 66 | To interprete the output, we may consider following values as rule-of-thumbs for indicating a reliable scale: 67 | 68 | * item difficulty should range between 0.2 and 0.8. Ideal value is p+(1-p)/2 (which mostly is between 0.5 and 0.8) 69 | * for item discrimination, acceptable values are 0.2 or higher; the closer to 1 the better 70 | * in case the total Cronbach's Alpha value is below the acceptable cut-off of 0.7 (mostly if an index has few items), the mean inter-item-correlation is an alternative measure to indicate acceptability; satisfactory range lies between 0.2 and 0.4 71 | 72 | ## Index score with more than one component 73 | 74 | The items of the COPE index used for our example do not represent a single factor. We can check this, for instance, with a principle component analysis. If you know, which variable belongs to which factor (i.e. which variable is part of which component), you can pass a numeric vector with these group indices to the argument `factor.groups`. In this case, the data frame is divided into the components specified by `factor.groups`, and each component (or factor) is analysed. 75 | 76 | ```{r} 77 | library(parameters) 78 | # Compute PCA on Cope-Index, and retrieve 79 | # factor indices for each COPE index variable 80 | pca <- parameters::principal_components(mydf) 81 | factor.groups <- parameters::closest_component(pca) 82 | ``` 83 | 84 | The PCA extracted two components. Now `tab_itemscale()` ... 85 | 86 | 1. performs an item analysis on both components, showing whether each of them is a reliable and useful scale or index score 87 | 2. builds an index of each component, by standardizing each scale 88 | 3. and adds a component-correlation-matrix, to see whether the index scores (which are based on the components) are highly correlated or not. 89 | 90 | ```{r} 91 | tab_itemscale(mydf, factor.groups) 92 | ``` 93 | 94 | ## Adding further statistics 95 | 96 | ```{r} 97 | tab_itemscale(mydf, factor.groups, show.shapiro = TRUE, show.kurtosis = TRUE) 98 | ``` 99 | 100 | -------------------------------------------------------------------------------- /vignettes/tab_bayes.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Summary of Bayesian Models as HTML Table" 3 | author: "Daniel Lüdecke" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | params: 7 | EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") 8 | --- 9 | 10 | 16 | 17 | ```{r echo = FALSE} 18 | knitr::opts_chunk$set( 19 | collapse = TRUE, 20 | comment = "#>", 21 | message = FALSE 22 | ) 23 | 24 | m1 <- m2 <- NULL 25 | 26 | if (!requireNamespace("insight", quietly = TRUE) || 27 | !requireNamespace("httr", quietly = TRUE) || 28 | !requireNamespace("brms", quietly = TRUE)) { 29 | knitr::opts_chunk$set(eval = FALSE) 30 | } else { 31 | knitr::opts_chunk$set(eval = TRUE) 32 | library(insight) 33 | library(httr) 34 | library(sjPlot) 35 | library(brms) 36 | m1 <- tryCatch(insight::download_model("brms_zi_2"), error = function(e) NULL) 37 | m2 <- tryCatch(insight::download_model("brms_mv_3"), error = function(e) NULL) 38 | } 39 | 40 | if (is.null(m1) || is.null(m2)) { 41 | knitr::opts_chunk$set(eval = FALSE) 42 | } 43 | ``` 44 | 45 | This vignette shows examples for using `tab_model()` to create HTML tables for mixed models. Basically, `tab_model()` behaves in a very similar way for mixed models as for other, simple regression models, as shown [in this vignette](tab_model_estimates.html). 46 | 47 | ```{r, results='hide', message=FALSE, warning=FALSE, eval=FALSE} 48 | # load required packages 49 | library(sjPlot) 50 | library(brms) 51 | 52 | # sample models 53 | zinb <- read.csv("http://stats.idre.ucla.edu/stat/data/fish.csv") 54 | set.seed(123) 55 | m1 <- brm(bf( 56 | count ~ persons + child + camper + (1 | persons), 57 | zi ~ child + camper + (1 | persons) 58 | ), 59 | data = zinb, 60 | family = zero_inflated_poisson() 61 | ) 62 | 63 | data(epilepsy) 64 | set.seed(123) 65 | epilepsy$visit <- as.numeric(epilepsy$visit) 66 | epilepsy$Base2 <- sample(epilepsy$Base, nrow(epilepsy), replace = TRUE) 67 | f1 <- bf(Base ~ zAge + count + (1 |ID| patient)) 68 | f2 <- bf(Base2 ~ zAge + Trt + (1 |ID| patient)) 69 | m2 <- brm(f1 + f2 + set_rescor(FALSE), data = epilepsy) 70 | ``` 71 | 72 | ## Bayesian models summaries as HTML table 73 | 74 | For Bayesian regression models, some of the differences to the table output from [simple models](tab_model_estimates.html) or [mixed models](tab_mixed.html) of `tab_models()` are the use of _Highest Density Intervals_ instead of confidence intervals, the Bayes-R-squared values, and a different "point estimate" (which is, by default, the median from the posterior draws). 75 | 76 | ```{r} 77 | tab_model(m1) 78 | ``` 79 | 80 | ## Multivariate response models 81 | 82 | For multivariate response models, like mediator-analysis-models, it is recommended to print just one model in the table, as each regression is displayed as own "model" in the output. 83 | 84 | ```{r} 85 | tab_model(m2) 86 | ``` 87 | 88 | ## Show two Credible Interval-column 89 | 90 | To show a second CI-column, use `show.ci50 = TRUE`. 91 | 92 | ```{r} 93 | tab_model(m2, show.ci50 = TRUE) 94 | ``` 95 | 96 | ## Mixing multivariate and univariate response models 97 | 98 | When both multivariate and univariate response models are displayed in one table, a column _Response_ is added for the multivariate response model, to indicate the different outcomes. 99 | 100 | ```{r} 101 | tab_model(m1, m2) 102 | ``` 103 | -------------------------------------------------------------------------------- /vignettes/tab_mixed.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Summary of Mixed Models as HTML Table" 3 | author: "Daniel Lüdecke" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | params: 7 | EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") 8 | --- 9 | 10 | 16 | 17 | ```{r echo = FALSE} 18 | knitr::opts_chunk$set( 19 | collapse = TRUE, 20 | comment = "#>", 21 | message = FALSE 22 | ) 23 | 24 | if (!requireNamespace("lme4", quietly = TRUE) || 25 | !requireNamespace("glmmTMB", quietly = TRUE)) { 26 | knitr::opts_chunk$set(eval = FALSE) 27 | } else { 28 | knitr::opts_chunk$set(eval = TRUE) 29 | } 30 | 31 | ``` 32 | 33 | This vignette shows examples for using `tab_model()` to create HTML tables for mixed models. Basically, `tab_model()` behaves in a very similar way for mixed models as for other, simple regression models, as shown [in this vignette](tab_model_estimates.html). 34 | 35 | ```{r, results='hide', message=FALSE, warning=FALSE} 36 | # load required packages 37 | library(sjPlot) 38 | library(lme4) 39 | data("sleepstudy") 40 | data("efc") 41 | efc$cluster <- as.factor(efc$e15relat) 42 | ``` 43 | 44 | ## Mixed models summaries as HTML table 45 | 46 | Unlike tables for [non-mixed models](tab_model_estimates.html), `tab_models()` adds additional information on the random effects to the table output for mixed models. You can hide these information with `show.icc = FALSE` and `show.re.var = FALSE`. Furthermore, the R-squared values are marginal and conditional R-squared statistics, based on _Nakagawa et al. 2017_. 47 | 48 | ```{r} 49 | m1 <- lmer(neg_c_7 ~ c160age + c161sex + e42dep + (1 | cluster), data = efc) 50 | m2 <- lmer(Reaction ~ Days + (1 + Days | Subject), data = sleepstudy) 51 | 52 | tab_model(m1, m2) 53 | ``` 54 | 55 | The marginal R-squared considers only the variance of the fixed effects, while the conditional R-squared takes both the fixed and random effects into account. 56 | 57 | The p-value is a simple approximation, based on the t-statistics and using the normal distribution function. A more precise p-value can be computed using `p.val = "kr"`. In this case, which only applies to linear mixed models, the computation of p-values is based on conditional F-tests with Kenward-Roger approximation for the degrees of freedom (using the using the **pbkrtest**-package). Note that here the computation is more time consuming and thus not used as default. You can also display the approximated degrees of freedom with `show.df`. 58 | 59 | ```{r} 60 | tab_model(m1, p.val = "kr", show.df = TRUE) 61 | ``` 62 | 63 | ## Generalized linear mixed models 64 | 65 | `tab_model()` can also print and combine models with different link-functions. 66 | 67 | ```{r} 68 | data("efc") 69 | efc$neg_c_7d <- ifelse(efc$neg_c_7 < median(efc$neg_c_7, na.rm = TRUE), 0, 1) 70 | efc$cluster <- as.factor(efc$e15relat) 71 | m3 <- glmer( 72 | neg_c_7d ~ c160age + c161sex + e42dep + (1 | cluster), 73 | data = efc, 74 | family = binomial(link = "logit") 75 | ) 76 | 77 | tab_model(m1, m3) 78 | ``` 79 | 80 | ## More complex models 81 | 82 | Finally, an example from the **glmmTMB**-package to show how easy it is to print zero-inflated generalized linear mixed models as HTML table. 83 | 84 | ```{r} 85 | library(glmmTMB) 86 | data("Salamanders") 87 | m4 <- glmmTMB( 88 | count ~ spp + mined + (1 | site), 89 | ziformula = ~ spp + mined, 90 | family = truncated_poisson(link = "log"), 91 | data = Salamanders 92 | ) 93 | 94 | tab_model(m1, m3, m4, show.ci = FALSE) 95 | ``` 96 | 97 | ## References 98 | 99 | Nakagawa S, Johnson P, Schielzeth H (2017) _The coefficient of determination R2 and intra-class correlation coefficient from generalized linear mixed-effects models revisted and expanded._ J. R. Soc. Interface 14. doi: 10.1098/rsif.2017.0213 100 | -------------------------------------------------------------------------------- /vignettes/tab_model_robust.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Robust Estimation of Standard Errors, Confidence Intervals and p-values" 3 | output: rmarkdown::html_vignette 4 | params: 5 | EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") 6 | --- 7 | 8 | 14 | 15 | ```{r message=FALSE, warning=FALSE, include=FALSE} 16 | knitr::opts_chunk$set( 17 | collapse = TRUE, 18 | comment = "#>", 19 | message = FALSE 20 | ) 21 | 22 | if (!requireNamespace("dplyr", quietly = TRUE) || 23 | !requireNamespace("sandwich", quietly = TRUE) || 24 | !requireNamespace("lme4", quietly = TRUE) || 25 | !requireNamespace("clubSandwich", quietly = TRUE)) { 26 | knitr::opts_chunk$set(eval = FALSE) 27 | } else { 28 | knitr::opts_chunk$set(eval = TRUE) 29 | library(sjPlot) 30 | library(dplyr) 31 | } 32 | 33 | set.seed(333) 34 | ``` 35 | 36 | The `tab_model()` function also allows the computation of standard errors, confidence intervals and p-values based on robust covariance matrix estimation from model parameters. Robust estimation is based on the packages **sandwich** and **clubSandwich**, so all models supported by either of these packages work with `tab_model()`. 37 | 38 | ## Classical Regression Models 39 | 40 | ### Robust Covariance Matrix Estimation from Model Parameters 41 | 42 | There are two arguments that allow for choosing different methods and options of robust estimation: `vcov.fun` and `vcov.args`. Let us start with a simple example, which uses a heteroskedasticity-consistent covariance matrix estimation with estimation-type "HC3" (i.e. `sandwich::vcovHC(type = "HC3")` is called): 43 | 44 | ```{r} 45 | data(iris) 46 | model <- lm(Petal.Length ~ Sepal.Length * Species + Sepal.Width, data = iris) 47 | 48 | # model parameters, where SE, CI and p-values are based on robust estimation 49 | tab_model(model, vcov.fun = "HC3", show.se = TRUE) 50 | 51 | # compare standard errors to result from sandwich-package 52 | unname(sqrt(diag(sandwich::vcovHC(model)))) 53 | ``` 54 | 55 | ### Cluster-Robust Covariance Matrix Estimation (sandwich) 56 | 57 | If another covariance matrix estimation is required, use the `vcov.fun`-argument. This argument needs the suffix for the related `vcov*()`-functions as value, i.e. `vcov.fun = "CL"` would call `sandwich::vcovCL()`, or `vcov.fun = "HAC"` would call `sandwich::vcovHAC()`. 58 | 59 | The specific estimation type can be changed with `vcov.args`. E.g., `sandwich::vcovCL()` accepts estimation types HC0 to HC3. In the next example, we use a clustered covariance matrix estimation with HC1-estimation type. 60 | 61 | ```{r} 62 | # change estimation-type 63 | tab_model(model, vcov.fun = "CL", vcov.args = list(type = "HC1"), show.se = TRUE) 64 | 65 | # compare standard errors to result from sandwich-package 66 | unname(sqrt(diag(sandwich::vcovCL(model)))) 67 | ``` 68 | 69 | Usually, clustered covariance matrix estimation is used when there is a cluster-structure in the data. The variable indicating the cluster-structure can be defined in `sandwich::vcovCL()` with the `cluster`-argument. In `tab_model()`, additional arguments that should be passed down to functions from the **sandwich** package can be specified in `vcov.args`: 70 | 71 | ```{r} 72 | iris$cluster <- factor(rep(LETTERS[1:8], length.out = nrow(iris))) 73 | # change estimation-type, defining additional arguments 74 | tab_model( 75 | model, 76 | vcov.fun = "CL", 77 | vcov.args = list(type = "HC1", cluster = iris$cluster), 78 | show.se = TRUE 79 | ) 80 | 81 | # compare standard errors to result from sandwich-package 82 | unname(sqrt(diag(sandwich::vcovCL(model, cluster = iris$cluster)))) 83 | ``` 84 | 85 | ### Cluster-Robust Covariance Matrix Estimation (clubSandwich) 86 | 87 | Cluster-robust estimation of the variance-covariance matrix can also be achieved using `clubSandwich::vcovCR()`. Thus, when `vcov.fun = "CR"`, the related function from the **clubSandwich** package is called. Note that this function _requires_ the specification of the `cluster`-argument. 88 | 89 | ```{r} 90 | # create fake-cluster-variable, to demonstrate cluster robust standard errors 91 | iris$cluster <- factor(rep(LETTERS[1:8], length.out = nrow(iris))) 92 | 93 | # cluster-robust estimation 94 | tab_model( 95 | model, 96 | vcov.fun = "CR1", 97 | vcov.args = list(cluster = iris$cluster), 98 | show.se = TRUE 99 | ) 100 | 101 | # compare standard errors to result from clubSsandwich-package 102 | unname(sqrt(diag(clubSandwich::vcovCR(model, type = "CR1", cluster = iris$cluster)))) 103 | ``` 104 | 105 | ### Robust Covariance Matrix Estimation on Standardized Model Parameters 106 | 107 | Finally, robust estimation can be combined with standardization. However, robust covariance matrix estimation only works for `show.std = "std"`. 108 | 109 | ```{r} 110 | # model parameters, robust estimation on standardized model 111 | tab_model( 112 | model, 113 | show.std = "std", 114 | vcov.fun = "HC" 115 | ) 116 | ``` 117 | 118 | ## Mixed Models 119 | 120 | ### Robust Covariance Matrix Estimation for Mixed Models 121 | 122 | For linear mixed models, that by definition have a clustered ("hierarchical" or multilevel) structure in the data, it is also possible to estimate a cluster-robust covariance matrix. This is possible due to the **clubSandwich** package, thus we need to define the same arguments as in the above example. 123 | 124 | ```{r} 125 | library(lme4) 126 | data(iris) 127 | set.seed(1234) 128 | iris$grp <- as.factor(sample(1:3, nrow(iris), replace = TRUE)) 129 | 130 | # fit example model 131 | model <- lme4::lmer( 132 | Sepal.Length ~ Species * Sepal.Width + Petal.Length + (1 | grp), 133 | data = iris 134 | ) 135 | 136 | # normal model parameters, like from 'summary()' 137 | tab_model(model) 138 | 139 | # model parameters, cluster robust estimation for mixed models 140 | tab_model( 141 | model, 142 | vcov.fun = "CR1", 143 | vcov.args = list(cluster = iris$grp) 144 | ) 145 | ``` 146 | 147 | ### Robust Covariance Matrix Estimation on Standardized Mixed Model Parameters 148 | 149 | Again, robust estimation can be combined with standardization for linear mixed models as well, which in such cases also only works for `show.std = "std"`. 150 | 151 | ```{r} 152 | # model parameters, cluster robust estimation on standardized mixed model 153 | tab_model( 154 | model, 155 | show.std = "std", 156 | vcov.fun = "CR1", 157 | vcov.args = list(cluster = iris$grp) 158 | ) 159 | ``` 160 | -------------------------------------------------------------------------------- /vignettes/table_css.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Customizing HTML tables" 3 | author: "Daniel Lüdecke" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Customizing HTML tables} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r echo = FALSE} 13 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>", warning = FALSE, message = FALSE) 14 | ``` 15 | 16 | All `tab_*`-functions create a HTML page with the table output. This table, by default, is opened in the viewer pane of your IDE (in case you’re using an IDE that also supports the viewer pane). If a viewer pane is not available, the created HTML output is saved as temporary file and opened in your default web browser. The temporary files are deleted after your R session ends. 17 | 18 | ## Copying table output to office or word processors 19 | 20 | ### Export table as HTML file to open in word processors 21 | 22 | You can save the HTML page as file for further usage by specifying the `file`-argument The saved HTML file can be opened by word processors like LibreOffice or Microsoft Office. 23 | 24 | ### Drag and drop from browser or RStudio viewer pane 25 | 26 | You can directly drag and drop a table from the RStudio viewer pane or browser into your word processor. Simply select the complete table with your mouse and drag it into office. 27 | 28 | ## Customizing table output with the CSS parameter 29 | 30 | The table output is in in HTML format. The table style (visual appearance) is formatted using _Cascading Style Sheets_ (CSS). If you are a bit familiar with these topics, you can easily customize the appearance of the table output. 31 | 32 | Many table elements (header, row, column, cell, summary row, first row or column...) have CSS-class attributes, which can be used to change the table style. Since each `sjt.*` function as well as `tab_model()` has different table elements and thus different class attributes, you first need to know which styles can be customized. 33 | 34 | ### Retrieving customizable styles 35 | 36 | The table functions invisibly return several values. The return value `page.style` contains the style information for the HTML table. You can print this style sheet to console using the `cat()`-function: 37 | 38 | ```{r} 39 | library(sjPlot) 40 | data(efc) 41 | m <- lm(barthtot ~ c160age + c12hour + c161sex + c172code, data = efc) 42 | tab <- tab_model(m) 43 | ``` 44 | 45 | ```{r echo = TRUE} 46 | cat(tab$page.style) 47 | ``` 48 | 49 | The HTML code is in the `page.content` return value. The following code prints the HTML code of the table to the R console: 50 | 51 | ```{r echo = TRUE} 52 | cat(tab$page.content) 53 | ``` 54 | 55 | Now you can see which table elements are associated with which CSS class attributes. 56 | 57 | ## Customizing table output with the CSS parameter 58 | 59 | You can customize the table output with the `CSS` parameter. This parameter requires a list of attributes, which follow a certain pattern: 60 | 61 | 1) each attributes needs a `css.` prefix 62 | 2) followed by the class name (e.g. `caption`, `thead`, `centeralign`, etc.) 63 | 3) equal-sign 64 | 4) the CSS format (in (single) quotation marks) 65 | 5) the CSS format must end with a colon (;) 66 | 67 | Example: 68 | 69 | ```{r} 70 | tab_model( 71 | m, 72 | CSS = list( 73 | css.depvarhead = 'color: red;', 74 | css.centeralign = 'text-align: left;', 75 | css.firsttablecol = 'font-weight: bold;', 76 | css.summary = 'color: blue;' 77 | ) 78 | ) 79 | ``` 80 | 81 | In the above example, the header row lost the original style and just became red. If you want to keep the original style and just add additional style information, use the plus-sign (+) as initial character for the parameter attributes. In the following example, the header row keeps its original style and is additionally printed in red: 82 | 83 | ```{r} 84 | tab_model(m, CSS = list(css.depvarhead = '+color: red;')) 85 | ``` 86 | 87 | ## Pre-defined Table-Layouts 88 | 89 | There are a few pre-defined CSS-themes, which can be accessed with the `css_theme()`-function. There are more pre-defined themes planned for the future. 90 | 91 | ```{r} 92 | tab_model(m, CSS = css_theme("cells")) 93 | ``` 94 | --------------------------------------------------------------------------------