├── .Rbuildignore ├── .github ├── .gitignore ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── bump_dev_version.yaml │ ├── check-standard.yaml │ ├── pkgdown.yaml │ └── test-coverage.yaml ├── .gitignore ├── .lintr ├── CRAN-SUBMISSION ├── DESCRIPTION ├── NAMESPACE ├── NEWS.md ├── R ├── burgled.R ├── compact.R ├── cross_by.R ├── cross_categorical.R ├── cross_numeric.R ├── cross_survival.R ├── crosstable-package.R ├── crosstable.R ├── dataset.R ├── effect.R ├── flextable.R ├── funs.R ├── gt.R ├── labels.R ├── methods.R ├── officer.R ├── openxlsx.R ├── options.R ├── pivot.R ├── reexport.R ├── test.R └── utils.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── codemeta.json ├── cran-comments.md ├── crosstable.Rproj ├── data-raw ├── iris2.R └── mtcars2.R ├── data ├── iris2.rda └── mtcars2.rda ├── examples ├── example_doc.docx ├── result_test_crosstable_officer.docx ├── test_legends_officer_v0.4.R ├── test_officer_v0.3.19_crosstable.rds ├── test_officer_v0.4_crosstable.rds ├── vignette_markdown.Rmd ├── vignette_markdown.docx └── vignette_officer.docx ├── inst ├── IMPORTLIST ├── WORDLIST └── template_ls_sm.docx ├── man ├── apply_labels.Rd ├── as_flextable.Rd ├── as_gt.Rd ├── as_workbook.Rd ├── body_add_crosstable.Rd ├── body_add_crosstable_footnote.Rd ├── body_add_gg2.Rd ├── body_add_img2.Rd ├── body_add_legend.Rd ├── body_add_list.Rd ├── body_add_normal.Rd ├── body_add_table_list.Rd ├── body_add_table_section.Rd ├── body_add_title.Rd ├── body_replace_text_at_bkms.Rd ├── clean_names_with_labels.Rd ├── confint_numeric.Rd ├── cross_summary.Rd ├── crosstable-package.Rd ├── crosstable.Rd ├── crosstable_effect_args.Rd ├── crosstable_options.Rd ├── crosstable_peek_options.Rd ├── crosstable_reset_options.Rd ├── crosstable_test_args.Rd ├── ct_compact.Rd ├── display_effect.Rd ├── display_test.Rd ├── docx_bookmarks2.Rd ├── effect_summary.Rd ├── effect_survival.Rd ├── effect_tabular.Rd ├── figures │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── ct.pptx │ ├── ct1.png │ ├── ct1_mod.png │ ├── ct1_mod_twitter.png │ ├── ct2.png │ ├── ct2_mod.png │ ├── ct2_mod_twitter.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── github-open-graph-crosstable.png │ ├── lifecycle-archived.svg │ ├── lifecycle-defunct.svg │ ├── lifecycle-deprecated.svg │ ├── lifecycle-experimental.svg │ ├── lifecycle-maturing.svg │ ├── lifecycle-questioning.svg │ ├── lifecycle-soft-deprecated.svg │ ├── lifecycle-stable.svg │ ├── lifecycle-superseded.svg │ ├── logo.png │ ├── officer-example.png │ ├── tests.pptx │ └── vignette_officer.docx ├── format_fixed.Rd ├── generate_autofit_macro.Rd ├── get_label.Rd ├── get_percent_pattern.Rd ├── import_labels.Rd ├── iris2.Rd ├── is.crosstable.Rd ├── mtcars2.Rd ├── n.Rd ├── na.Rd ├── narm.Rd ├── peek.Rd ├── pivot_crosstable.Rd ├── plim.Rd ├── reexports.Rd ├── remove_labels.Rd ├── rename_with_labels.Rd ├── set_label.Rd ├── summaryFunctions.Rd ├── test_correlation_auto.Rd ├── test_summarize_auto.Rd ├── test_summarize_linear_contrasts.Rd ├── test_survival_logrank.Rd ├── test_tabular_auto.Rd ├── transpose_crosstable.Rd └── write_and_open.Rd ├── pkgdown ├── extra.css ├── extra.js └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── revdep ├── .gitignore ├── README.md ├── cran.md ├── failures.md └── problems.md ├── tests ├── testthat.R └── testthat │ ├── _snaps │ ├── by_factor.md │ ├── by_numeric.md │ ├── compact.md │ ├── crosstable.md │ ├── effects_snap.md │ ├── flextable.md │ ├── labels.md │ ├── methods.md │ ├── officer.md │ ├── options.md │ ├── pivot.md │ ├── quick_surv.md │ ├── selection.md │ └── tests.md │ ├── docx │ └── 4-officer │ │ ├── snap_crosstables_double_with_effects.docx │ │ ├── snap_crosstables_double_with_effects_new.docx │ │ ├── snap_crosstables_helpers.docx │ │ ├── snap_crosstables_simple.docx │ │ ├── snap_crosstables_simple_new.docx │ │ ├── snap_crosstables_triple.docx │ │ ├── snap_crosstables_triple_new.docx │ │ ├── snap_utils_functions.docx │ │ ├── snap_utils_functions_are_ok_too.docx │ │ └── snap_utils_functions_new.docx │ ├── helper-init_dataset.R │ ├── test-by_factor.R │ ├── test-by_numeric.R │ ├── test-compact.R │ ├── test-crosstable.R │ ├── test-effects.R │ ├── test-effects_snap.R │ ├── test-flextable.R │ ├── test-labels.R │ ├── test-methods.R │ ├── test-officer.R │ ├── test-options.R │ ├── test-pivot.R │ ├── test-quick_surv.R │ ├── test-selection.R │ ├── test-tests.R │ ├── todo_test-1-crosstable-v2.R │ ├── todo_tests.R │ └── xlsx │ ├── test_openxlsx1.xlsx │ ├── test_openxlsx2.xlsx │ ├── test_openxlsx3.xlsx │ ├── test_openxlsx4.xlsx │ ├── test_openxlsx5.xlsx │ └── test_openxlsx6.xlsx └── vignettes ├── .gitignore ├── crosstable-report.Rmd ├── crosstable-selection.Rmd ├── crosstable.Rmd ├── officer-example.png └── percent_pattern.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | .git 2 | .git/* 3 | .Rproj.user* 4 | man/figures/* 5 | examples/* 6 | 7 | 8 | TODO\.R 9 | DEV\.R 10 | ^R/dev-.*\.R$ 11 | ^R/knit_print_debug\.R$ 12 | 13 | .*~.* 14 | 15 | ^README.Rmd$ 16 | ^\.lintr$ 17 | ^.*\.Rproj$ 18 | ^.*\.RData$ 19 | ^\.github$ 20 | ^\.Rproj\.user$ 21 | ^\.travis\.yml$ 22 | ^_pkgdown\.yml$ 23 | ^codecov\.yml$ 24 | ^cran-comments\.md$ 25 | ^doc$ 26 | ^Meta$ 27 | ^data-raw$ 28 | ^docs$ 29 | ^pkgdown$ 30 | ^CRAN-RELEASE$ 31 | ^codemeta\.json$ 32 | ^CRAN-SUBMISSION$ 33 | ^revdep$ 34 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | Please be as clear and thorough as possible. 12 | 13 | **Reproducible example** 14 | Share the code that caused the bug, along with all error and warning messages. 15 | Please also use `dput(df)` to provide a sample dataset so I can reproduce the error. If your dataset is too large, select a minimal number of columns and rows, or use https://pastebin.com/. 16 | 17 | **Session info** 18 |
19 | ``` r 20 | #Paste here the output of `sessionInfo()` here 21 | ``` 22 |
23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an improvement 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the new feature** 11 | Please be as clear and thorough as possible. 12 | 13 | **Known workaround** 14 | If you know any workaround, please share the code here. 15 | -------------------------------------------------------------------------------- /.github/workflows/bump_dev_version.yaml: -------------------------------------------------------------------------------- 1 | on: [push, workflow_dispatch] 2 | 3 | name: Bump dev version 4 | 5 | jobs: 6 | update_version: 7 | runs-on: ubuntu-latest 8 | env: 9 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 10 | steps: 11 | - name: Check out repository 12 | uses: actions/checkout@v4 13 | - name: Set up R 14 | uses: r-lib/actions/setup-r@v2 15 | - name: Bump dev version 16 | uses: DanChaltiel/actions/bump-dev-version@v1 17 | with: 18 | create-tag: true 19 | -------------------------------------------------------------------------------- /.github/workflows/check-standard.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macos-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v3 33 | 34 | - uses: r-lib/actions/setup-pandoc@v2 35 | 36 | - uses: r-lib/actions/setup-r@v2 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v2 43 | with: 44 | extra-packages: any::rcmdcheck 45 | needs: check 46 | 47 | - uses: r-lib/actions/check-r-package@v2 48 | with: 49 | upload-snapshots: true 50 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::pkgdown, local::. 34 | needs: website 35 | 36 | - name: Build site 37 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 38 | shell: Rscript {0} 39 | 40 | - name: Deploy to GitHub pages 🚀 41 | if: github.event_name != 'pull_request' 42 | uses: JamesIves/github-pages-deploy-action@v4.4.1 43 | with: 44 | clean: false 45 | branch: gh-pages 46 | folder: docs 47 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::covr 27 | needs: coverage 28 | 29 | - name: Test coverage 30 | run: | 31 | covr::codecov( 32 | quiet = FALSE, 33 | clean = FALSE, 34 | install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package") 35 | ) 36 | shell: Rscript {0} 37 | 38 | - name: Show testthat output 39 | if: always() 40 | run: | 41 | ## -------------------------------------------------------------------- 42 | find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true 43 | shell: bash 44 | 45 | - name: Upload test results 46 | if: failure() 47 | uses: actions/upload-artifact@v3 48 | with: 49 | name: coverage-test-failures 50 | path: ${{ runner.temp }}/package 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # RStudio internals 3 | .Rproj.user 4 | *.RData 5 | *.Rhistory 6 | crosstable.Rcheck/ 7 | 8 | # this messes up github linguistics (see https://github.com/github/linguist/issues/4927) 9 | pkgdown/index\.html 10 | 11 | # MS Word files 12 | test*.docx 13 | ~*.docx 14 | 15 | #test files 16 | TODO.R 17 | dev-*.R 18 | 19 | # Windows image file caches 20 | Thumbs.db 21 | ehthumbs.db 22 | 23 | # Folder config file 24 | Desktop.ini 25 | 26 | .RData 27 | .Rproj.user* 28 | .Rhistory 29 | .Rprofile 30 | 31 | /doc/ 32 | /docs/ 33 | /Meta/ 34 | 35 | *~* 36 | inst/doc 37 | examples/example_result.png 38 | examples/example_code.png 39 | 40 | TODO\.R 41 | DEV\.R 42 | tests/testthat/test-dummy.R 43 | .Renviron 44 | cran-comments.md 45 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | 2 | 3 | linters: with_defaults( 4 | line_length_linter(100), 5 | assignment_linter = NULL 6 | ) 7 | exclusions: list("R/burgled.R") 8 | encoding: "UTF-8" 9 | -------------------------------------------------------------------------------- /CRAN-SUBMISSION: -------------------------------------------------------------------------------- 1 | Version: 0.8.1 2 | Date: 2024-11-01 10:09:30 UTC 3 | SHA: 2933977ecc3f8377a4bc4d095d9e64d95063361e 4 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: crosstable 2 | Title: Crosstables for Descriptive Analyses 3 | Version: 0.8.1.9003 4 | Authors@R: 5 | c(person(given = "Dan", 6 | family = "Chaltiel", 7 | role = c("aut", "cre"), 8 | email = "dan.chaltiel@gmail.com", 9 | comment = c(ORCID = "0000-0003-3488-779X")), 10 | person(given = "David", 11 | family = "Hajage", 12 | role = "ccp")) 13 | Description: Create descriptive tables for continuous and categorical variables. 14 | Apply summary statistics and counting function, with or without a grouping variable, and create beautiful reports using 'rmarkdown' or 'officer'. 15 | You can also compute effect sizes and statistical tests if needed. 16 | License: GPL-3 17 | URL: https://danchaltiel.github.io/crosstable/, https://github.com/DanChaltiel/crosstable/ 18 | BugReports: https://github.com/DanChaltiel/crosstable/issues/ 19 | Depends: 20 | R (>= 3.1.0) 21 | Imports: 22 | checkmate (>= 1.9.0), 23 | cli (>= 3.0.0), 24 | dplyr (>= 1.1.0), 25 | flextable (>= 0.5.1), 26 | forcats (>= 1.0.0), 27 | glue (>= 1.3.0), 28 | lifecycle (>= 0.2.0), 29 | methods, 30 | officer (>= 0.4.0), 31 | purrr (>= 0.2.3), 32 | rlang (>= 1.0.0), 33 | stats, 34 | stringr (>= 1.4.0), 35 | tibble (>= 1.1), 36 | tidyr (>= 1.0.0), 37 | utils, 38 | Suggests: 39 | callr, 40 | covr, 41 | crayon, 42 | xml2, 43 | digest, 44 | gt, 45 | expss, 46 | ggplot2, 47 | gmodels, 48 | Hmisc, 49 | hms, 50 | jsonlite, 51 | knitr, 52 | lubridate, 53 | openxlsx, 54 | rmarkdown, 55 | sloop, 56 | stringi, 57 | survival, 58 | systemfonts, 59 | tidyselect, 60 | testthat (>= 3.0.0), 61 | withr, 62 | waldo 63 | VignetteBuilder: 64 | knitr 65 | Encoding: UTF-8 66 | LazyData: true 67 | Roxygen: list(markdown = TRUE) 68 | RoxygenNote: 7.3.2 69 | Config/testthat/edition: 3 70 | Config/testthat/parallel: true 71 | Config/testthat/start-first: by_factor , effects, officer 72 | -------------------------------------------------------------------------------- /R/burgled.R: -------------------------------------------------------------------------------- 1 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | # ad.test (copied from nortest:::ad.test) 3 | # from nortest 1.0-4 4 | #' @importFrom stats complete.cases pnorm sd 5 | `ad.test` <- function(x) { 6 | DNAME <- deparse(substitute(x)) 7 | x <- sort(x[complete.cases(x)]) 8 | n <- length(x) 9 | if (n < 8) { 10 | stop("sample size must be greater than 7") 11 | } 12 | logp1 <- pnorm((x - mean(x)) / sd(x), log.p = TRUE) 13 | logp2 <- pnorm(-(x - mean(x)) / sd(x), log.p = TRUE) 14 | h <- (2 * seq(1:n) - 1) * (logp1 + rev(logp2)) 15 | A <- -n - mean(h) 16 | AA <- (1 + 0.75 / n + 2.25 / n^2) * A 17 | if (AA < 0.2) { 18 | pval <- 1 - exp(-13.436 + 101.14 * AA - 223.73 * AA^2) 19 | } else if (AA < 0.34) { 20 | pval <- 1 - exp(-8.318 + 42.796 * AA - 59.938 * AA^2) 21 | } else if (AA < 0.6) { 22 | pval <- exp(0.9177 - 4.279 * AA - 1.38 * AA^2) 23 | } else if (AA < 10) { 24 | pval <- exp(1.2937 - 5.709 * AA + 0.0186 * AA^2) 25 | } else { 26 | pval <- 3.7e-24 27 | } 28 | RVAL <- list( 29 | statistic = c(A = A), p.value = pval, method = "Anderson-Darling normality test", 30 | data.name = DNAME 31 | ) 32 | class(RVAL) <- "htest" 33 | return(RVAL) 34 | } 35 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 36 | # CochranArmitageTest (copied from DescTools:::CochranArmitageTest) 37 | # from DescTools 0.99.42 38 | #' @importFrom stats pnorm 39 | `CochranArmitageTest` <- function(x, alternative = c("two.sided", "increasing", "decreasing")) { 40 | DNAME <- deparse(substitute(x)) 41 | if (!(any(dim(x) == 2))) { 42 | stop("Cochran-Armitage test for trend must be used with rx2-table", 43 | call. = FALSE 44 | ) 45 | } 46 | if (dim(x)[2] != 2) { 47 | x <- t(x) 48 | } 49 | nidot <- apply(x, 1, sum) 50 | n <- sum(nidot) 51 | Ri <- 1:dim(x)[1] 52 | Rbar <- sum(nidot * Ri) / n 53 | s2 <- sum(nidot * (Ri - Rbar)^2) 54 | pdot1 <- sum(x[, 1]) / n 55 | z <- sum(x[, 1] * (Ri - Rbar)) / sqrt(pdot1 * (1 - pdot1) * 56 | s2) 57 | STATISTIC <- z 58 | alternative <- match.arg(alternative) 59 | PVAL <- switch(alternative, 60 | two.sided = 2 * pnorm(abs(z), 61 | lower.tail = FALSE 62 | ), 63 | increasing = pnorm(z), 64 | decreasing = pnorm(z, 65 | lower.tail = FALSE 66 | ) 67 | ) 68 | PARAMETER <- dim(x)[1] 69 | names(STATISTIC) <- "Z" 70 | names(PARAMETER) <- "dim" 71 | METHOD <- "Cochran-Armitage test for trend" 72 | structure(list( 73 | statistic = STATISTIC, parameter = PARAMETER, 74 | alternative = alternative, p.value = PVAL, method = METHOD, 75 | data.name = DNAME 76 | ), class = "htest") 77 | } 78 | -------------------------------------------------------------------------------- /R/cross_by.R: -------------------------------------------------------------------------------- 1 | 2 | #' @importFrom cli cli_abort cli_warn 3 | #' @importFrom dplyr filter pull 4 | #' @importFrom glue glue glue_data 5 | #' @importFrom purrr imap list_rbind 6 | #' @importFrom rlang env 7 | #' @importFrom stats na.omit 8 | #' @keywords internal 9 | #' @noRd 10 | cross_by = function(data_x, data_y, funs, funs_arg, percent_pattern, total, percent_digits, 11 | showNA, label, test, times, followup, drop_levels, remove_zero_percent, 12 | test_args, cor_method, effect, effect_args){ 13 | if(!is.null(data_y) && ncol(data_y)>1) cli_abort(glue("data_y has {ncol(data_y)} columns (max=1)")) 14 | errors = rlang::env() 15 | 16 | if(isTRUE(drop_levels) & is.factor(data_y[[1]])) data_y[[1]] = fct_drop(data_y[[1]]) 17 | 18 | by_levels = length(unique(na.omit(data_y[[1]]))) 19 | if(!is.numeric(data_y[[1]]) && isTRUE(effect) && by_levels!=2){ 20 | cli_warn(c("Cannot calculate crosstable effects as there is not exactly 2 groups in `by`.", 21 | i="`by` has {by_levels} level{?s}"), 22 | class = "crosstable_effect_2groups_warning", 23 | call = crosstable_caller$env) 24 | effect = FALSE 25 | } 26 | 27 | rtn_tbl = imap(data_x, ~{ 28 | if(is.period(.x)){ 29 | .x = as.numeric(.x) %>% copy_label_from(.x) %>% structure(is_period=TRUE) 30 | } 31 | 32 | if(anyNA(.x) && "NA" %in% .x) { 33 | .x = if_else(.x!="NA", .x, factor("\"NA\"")) 34 | if(is.factor(.x)) .x = fct_drop(.x, only="NA") 35 | } 36 | if(!is.list(.x)){ #TODO is.list pour les erreurs, mieux vaudrait une classe spéciale? 37 | data_x[.y] = .x 38 | # errors[[.y]] = data.frame(name=.y, class="list") 39 | # return(NULL) 40 | } 41 | 42 | 43 | if(showNA=="no"){ 44 | if(is.null(data_y)){ 45 | data_x = data_x %>% filter(!is.na(data_x[[.y]])) 46 | } else { 47 | cc = !is.na(data_x[[.y]]) & !is.na(data_y[[1]]) 48 | data_x = data_x %>% filter(cc) 49 | data_y = data_y %>% filter(cc) 50 | } 51 | } 52 | 53 | if(is.list(.x)){ 54 | rtn=NULL 55 | } else if(is.numeric.and.not.surv(.x) || is.date(.x) || is.period(.x)){ 56 | rtn=cross_numeric(data_x[.y], data_y, funs=funs, funs_arg=funs_arg, 57 | showNA=showNA, total=total, label=label, 58 | cor_digits=percent_digits, cor_method=cor_method, 59 | test=test, test_args=test_args, effect=effect, effect_args=effect_args) 60 | } else if(is.character.or.factor(.x)){ 61 | rtn=cross_categorical(data_x[.y], data_y, percent_pattern=percent_pattern, 62 | showNA=showNA, total=total, label=label, percent_digits=percent_digits, 63 | drop_levels=drop_levels, remove_zero_percent=remove_zero_percent, 64 | test=test, test_args=test_args, effect=effect, effect_args=effect_args) 65 | } else if(is.Surv(.x)){ 66 | rtn=cross_survival(data_x[.y], data_y, times=times, followup=followup, 67 | showNA=showNA, total=total, label=label, surv_digits=percent_digits, 68 | test=test, test_args=test_args, effect=effect, effect_args=effect_args) 69 | } else { 70 | rtn=NULL 71 | } 72 | if(is.null(rtn)){ 73 | errors[[.y]] = data.frame(name=.y, class=paste_classes(.x)) 74 | } 75 | 76 | rtn 77 | }) %>% list_rbind() 78 | 79 | 80 | errors = as.list(errors) %>% list_rbind() 81 | if(nrow(errors)>0){ 82 | errors_s = glue_data(errors, "'{name}' ({class})") 83 | by_col = glue("'{names(data_y[1])}' ({paste_classes(data_y[[1]])})") 84 | if(is.null(data_y)){ 85 | cli_warn("Could not describe column{?s} of wrong class: {errors_s}", 86 | class = "crosstable_wrong_col_class_warning", 87 | call = crosstable_caller$env) 88 | } else { 89 | cli_warn("Could not cross {qty(errors_s)} column{?s} {errors_s} by column {by_col})", 90 | class = "crosstable_wrong_col_class_by_warning", 91 | call = crosstable_caller$env) 92 | } 93 | } 94 | 95 | if("effect" %in% names(rtn_tbl) && any(rtn_tbl$effect=="No effect?")){ 96 | x=rtn_tbl %>% filter(effect=="No effect?") %>% pull(.data$.id) %>% unique() 97 | cli_warn("Cannot calculate crosstable effects for variable{?s} {.var {x}}", 98 | class = "crosstable_effect_other_warning") 99 | } 100 | 101 | rownames(rtn_tbl)=NULL 102 | return(rtn_tbl) 103 | } 104 | -------------------------------------------------------------------------------- /R/cross_numeric.R: -------------------------------------------------------------------------------- 1 | 2 | #' @keywords internal 3 | #' @importFrom checkmate assert assert_numeric 4 | #' @importFrom dplyr everything mutate rename select 5 | #' @importFrom tibble as_tibble 6 | #' @noRd 7 | cross_numeric = function(data_x, data_y, funs, funs_arg, showNA, total, 8 | label, cor_digits, cor_method, test, test_args, effect, effect_args) { 9 | assert(ncol(data_x)==1) 10 | assert(is.null(data_y) || ncol(data_y)==1) 11 | assert_numeric(data_x[[1]]) 12 | 13 | if(label){ 14 | x_name = get_label(data_x) 15 | y_name = get_label(data_y) 16 | } else { 17 | x_name = names(data_x) 18 | y_name = names(data_y) 19 | } 20 | 21 | if(is.null(data_y)){ 22 | rtn = summarize_numeric_single(data_x[[1]], funs, funs_arg) 23 | } else if(is.character.or.factor(data_y[[1]])) { 24 | rtn = summarize_numeric_factor(data_x[[1]], data_y[[1]], funs, funs_arg, showNA, total, 25 | cor_digits, cor_method, test, test_args, 26 | effect, effect_args) 27 | } else if(!is.date(data_x[[1]]) && is.numeric.and.not.surv(data_y[[1]])){ 28 | rtn = summarize_numeric_numeric(data_x[[1]], data_y[[1]], method=cor_method, 29 | digits=cor_digits, test=test, test_args) %>% 30 | rename(!!y_name:="value") 31 | } else { 32 | return(NULL) 33 | } 34 | 35 | rtn = rtn %>% 36 | rename("label2"=any_of("label")) %>% 37 | mutate(.id=names(data_x), label=unname(x_name)) %>% 38 | select(".id", "label", everything()) %>% 39 | as_tibble() 40 | 41 | rtn 42 | } 43 | 44 | 45 | #' Summarize numeric variables 46 | #' @importFrom cli cli_abort 47 | #' @importFrom dplyr across mutate where 48 | #' @importFrom purrr discard imap list_rbind 49 | #' @keywords internal 50 | #' @noRd 51 | summarize_numeric_single = function(x, funs, funs_arg){ 52 | imap(funs, ~{ 53 | funs_arg2 = funs_arg 54 | if(!"..." %in% formal_args(.x)){ 55 | funs_arg2 = funs_arg[formal_args(.x)] %>% discard(is.null) 56 | } 57 | v = do.call(.x, c(list(x), funs_arg2)) 58 | if(length(v)<2){ 59 | variable = .y 60 | } else { 61 | variable=names(v) 62 | if(.y!=" "){ 63 | variable = paste(.y, variable) 64 | } 65 | } 66 | if(length(variable)!=length(v)){ 67 | cli_abort("Summary functions should return a single value", 68 | class="crosstable_summary_not_scalar") 69 | } 70 | 71 | data.frame(variable=variable, value=v) %>% 72 | mutate(across(where(~is.numeric(.x)||is.date(.x)), 73 | ~format_fixed(.x, !!!funs_arg))) 74 | }) %>% list_rbind() 75 | } 76 | 77 | 78 | #' Summarize numeric by categorical 79 | #' @importFrom checkmate assert_numeric assert_scalar 80 | #' @importFrom dplyr across everything mutate ungroup 81 | #' @importFrom forcats fct_na_value_to_level 82 | #' @importFrom purrr imap list_rbind 83 | #' @importFrom tidyr pivot_wider 84 | #' @keywords internal 85 | #' @noRd 86 | summarize_numeric_factor = function(x, by, funs, funs_arg, showNA, total, 87 | cor_digits, cor_method, test, test_args, 88 | effect, effect_args){ 89 | assert_numeric(x) 90 | assert_scalar(showNA) 91 | .na=.effect=.test=.total=NULL 92 | .showNA = showNA == "always" | (showNA == "ifany" && anyNA(by)) 93 | 94 | if(effect){ 95 | .effect = effect_args$effect_display(effect_args$effect_summarize(x, by, effect_args$conf_level), 96 | digits = cor_digits) 97 | } 98 | if(test){ 99 | .test = test_args$test_display(test_args$test_summarize(x, by), digits = test_args$plim, 100 | method = test_args$show_method) 101 | } 102 | if(identical(total, 1) | identical(total, 1:2) | identical(total, TRUE)){ 103 | .total = summarize_numeric_single(x, funs=funs, funs_arg=funs_arg)[["value"]] 104 | } 105 | 106 | if(.showNA==TRUE) { 107 | if(!anyNA(by)) .na="no NA" 108 | by_filter=TRUE 109 | by = fct_na_value_to_level(by, "NA") 110 | } else{ 111 | by_filter = !is.na(by) 112 | } 113 | 114 | by(x[by_filter], by[by_filter], summarize_numeric_single, funs=funs, funs_arg=funs_arg) %>% 115 | imap(~{ 116 | if(is.null(.x)) .x=summarize_numeric_single(numeric(0), funs=funs, funs_arg=funs_arg) 117 | mutate(.x, by=.y, .before=1) 118 | }) %>% 119 | list_rbind() %>% 120 | pivot_wider(names_from = "by") %>% 121 | {if(!is.null(.na)){mutate(.,"NA"=.na)} else .} %>% 122 | mutate(Total=.total, effect=.effect, test=.test, 123 | across(everything(), as.character)) %>% 124 | ungroup() 125 | } 126 | 127 | 128 | 129 | #' Summarize numeric by numeric (correlation) 130 | #' @importFrom checkmate assert_count assert_list assert_logical assert_numeric assert_string 131 | #' @importFrom dplyr mutate 132 | #' @importFrom glue glue 133 | #' @importFrom tibble tibble 134 | #' @keywords internal 135 | #' @noRd 136 | summarize_numeric_numeric = function(x, by, method, digits, test, test_args){ 137 | assert_numeric(x) 138 | assert_numeric(by) 139 | assert_string(method) 140 | assert_count(digits) 141 | assert_logical(test) 142 | assert_list(test_args) 143 | 144 | ct=test_args$test_correlation(x, by, method=method) 145 | 146 | cor=round(ct$estimate, digits=digits) 147 | if(!is.null(ct$conf.int)){ 148 | ci=round(ct$conf.int, digits=digits) 149 | value=glue("{cor} \n95%CI [{ci[1]};{ci[2]}]") 150 | } else { 151 | value=glue("{cor}") 152 | } 153 | 154 | if(test) .test=test_args$test_display(ct) else .test=NULL 155 | 156 | tibble(variable=method, value=as.character(value)) %>% mutate(test=.test) 157 | } 158 | -------------------------------------------------------------------------------- /R/crosstable-package.R: -------------------------------------------------------------------------------- 1 | #' @details 2 | #' The `crosstable`package is centered on the [crosstable()]` function. 3 | #' See vignettes for more information. 4 | #' @keywords internal 5 | #' @name crosstable-package 6 | #' @aliases crosstable-package 7 | ## usethis namespace: start 8 | #' @importFrom dplyr %>% 9 | #' @importFrom cli qty 10 | #' @importFrom rlang := 11 | ## usethis namespace: end 12 | "_PACKAGE" 13 | 14 | -------------------------------------------------------------------------------- /R/dataset.R: -------------------------------------------------------------------------------- 1 | #' Modified `mtcars` dataset 2 | #' 3 | #' @description 4 | #' Modified `mtcars` dataset so: 5 | #' + every column is labelled (using `label` attribute) 6 | #' + rownames are a character column named `model` 7 | #' + `gear` and `cyl` columns are considered as numerical factors 8 | #' + `vs` and `am` columns are considered as character vector 9 | #' 10 | #' See \code{\link{mtcars}} for more informations on the original "Motor Trend Car Road Tests" dataset. 11 | #' 12 | #' @format A data frame with 32 observations on 11 variables with labels. 13 | #' 14 | #' @source \preformatted{ 15 | #' library(dplyr) 16 | #' mtcars2 = mtcars \%>\% 17 | #' mutate( 18 | #' model=rownames(mtcars), 19 | #' vs=ifelse(vs==0, "vshaped", "straight"), 20 | #' am=ifelse(am==0, "auto", "manual"), 21 | #' across(c("cyl", "gear"), factor), 22 | #' .before=1 23 | #' ) \%>\% 24 | #' expss::apply_labels( #I also could have used [import_labels] or even `labelled::set_variable_labels()` 25 | #' mpg="Miles/(US) gallon", 26 | #' cyl="Number of cylinders", 27 | #' disp="Displacement (cu.in.)", 28 | #' hp="Gross horsepower", 29 | #' drat="Rear axle ratio", 30 | #' wt="Weight (1000 lbs)", 31 | #' qsec="1/4 mile time", 32 | #' vs="Engine", 33 | #' am="Transmission", 34 | #' gear="Number of forward gears", 35 | #' carb="Number of carburetors" 36 | #' ) 37 | #' } 38 | #' 39 | #' @examples 40 | #' library(crosstable) 41 | #' ct=crosstable(mtcars2, by=vs) 42 | #' ct 43 | #' as_flextable(ct) 44 | "mtcars2" 45 | 46 | 47 | #' Modified `iris` dataset 48 | #' 49 | #' @description 50 | #' Modified `iris` dataset so: 51 | #' + every column is labelled (using `label` attribute) 52 | #' + `Species` column is considered as factor 53 | #' 54 | #' See \code{\link{iris}} for more informations on the original "Edgar Anderson's Iris Data" dataset. 55 | #' 56 | #' @format A data frame with 150 observations on 5 variables with labels. 57 | #' 58 | #' @source \preformatted{ 59 | #' library(dplyr) 60 | #' iris2 = iris \%>\% 61 | #' expss::apply_labels( #I also could have used [import_labels] or even `labelled::set_variable_labels()` 62 | #' Species = "Specie", 63 | #' Sepal.Length = "Length of Sepal", 64 | #' Sepal.Width = "Width of Sepal", 65 | #' Petal.Length = "Length of Petal", 66 | #' Petal.Width = "Width of Petal" 67 | #' ) \%>\% 68 | #' as_tibble() 69 | #' } 70 | #' 71 | #' @examples 72 | #' library(crosstable) 73 | #' ct=crosstable(iris2, by=Species) 74 | #' ct 75 | #' as_flextable(ct) 76 | "iris2" 77 | -------------------------------------------------------------------------------- /R/gt.R: -------------------------------------------------------------------------------- 1 | #' Converts a `crosstable` object into a formatted `gt` table. 2 | #' 3 | #' @param x the result of [crosstable()] 4 | #' @param show_test_name in the `test` column, show the test name 5 | #' @param by_header a string to override the `by` header 6 | #' @param keep_id whether to keep the `.id` column 7 | #' @param generic_labels names of the crosstable default columns 8 | #' @param ... unused 9 | #' 10 | #' @return a formatted `gt` table 11 | #' 12 | #' @author Dan Chaltiel 13 | #' @family as_gt methods 14 | #' @describeIn as_gt For crosstables 15 | #' @seealso [as_flextable.crosstable()] 16 | #' 17 | #' @author Dan Chaltiel 18 | #' @export 19 | #' @importFrom checkmate assert_class vname 20 | #' @importFrom cli cli_abort 21 | #' @importFrom dplyr across any_of everything lag mutate select 22 | #' @importFrom glue glue 23 | #' @importFrom stringr str_remove 24 | #' @importFrom tidyr replace_na 25 | #' 26 | #' @examples 27 | #' xx = mtcars2 %>% dplyr::select(2:10) 28 | #' crosstable(xx) %>% as_gt 29 | #' crosstable(xx, by=am) %>% as_gt 30 | #' crosstable(xx, by=cyl, test=TRUE, total=TRUE) %>% 31 | #' as_gt(keep_id=TRUE, show_test_name=FALSE, by_header="Cylinders") 32 | as_gt.crosstable = function(x, show_test_name = TRUE, 33 | by_header = NULL, keep_id = FALSE, 34 | generic_labels=list(id = ".id", variable = "variable", value = "value", 35 | total="Total", label = "label", test = "test", 36 | effect="effect"), 37 | ...) { 38 | 39 | assert_class(x, "crosstable", .var.name=vname(x)) 40 | if (inherits(x, "compacted_crosstable")) { 41 | cli_abort("{.fun as_gt} is not implemented for compacted crosstables yet.", 42 | class="gt_compact_not_implemented_error") 43 | } 44 | if (inherits(x, "crosstable_multiby")) { 45 | cli_abort("{.fun as_gt} is not implemented for multi-by crosstables yet.", 46 | class="gt_multiby_not_implemented_error") 47 | } 48 | 49 | by_label = attr(x, "by_label") 50 | by_levels = attr(x, "by_levels") %>% unlist() %>% unname() %>% replace_na("NA") 51 | by = attr(x, "by") 52 | has_by = !is.null(by) 53 | if(has_by && is.null(by_label)) by_label=by 54 | showNA = attr(x, "showNA") 55 | if(showNA=="always") by_levels=c(by_levels, "NA") 56 | has_test = attr(x, "has_test") 57 | 58 | generic_labels = get_generic_labels(generic_labels) 59 | id=generic_labels$id 60 | label=generic_labels$label 61 | test=generic_labels$test 62 | 63 | if (has_test && !is.null(x[[test]]) && !show_test_name) { 64 | x[[test]] = str_remove(x[[test]], "\\n\\(.*\\)") 65 | } 66 | 67 | if(keep_id) { 68 | group_glue="{label} (`{.id}`)" 69 | } else { 70 | group_glue="{label}" 71 | } 72 | 73 | rtn = x %>% 74 | mutate( 75 | across(everything(), ~replace_na(.x, replace="NA")), 76 | across(any_of(c("test", "effect")), 77 | ~ifelse(is.na(lag(.x)) | .x!=lag(.x), .x, "")), 78 | groupname=glue(group_glue)) %>% 79 | select(-".id", -"label") %>% 80 | gt::gt(groupname_col="groupname", rowname_col="variable") 81 | if(has_by){ 82 | if(!is.null(by_header)) by_label=by_header 83 | rtn = rtn %>% 84 | gt::tab_spanner(label=by_label, columns=any_of(by_levels)) 85 | } else if(!is.null(by_header)){ 86 | rtn = rtn %>% 87 | gt::cols_label(!!generic_labels$value:=by_header) 88 | } 89 | 90 | rtn 91 | } 92 | 93 | 94 | #' Method to convert an object to a `gt` table 95 | #' 96 | #' @param x object to be converted 97 | #' @param ... arguments for custom methods 98 | #' 99 | #' @family as_gt methods 100 | #' @seealso [gt::gt()] 101 | #' @author Dan Chaltiel 102 | #' @export 103 | #' @importFrom rlang check_installed 104 | as_gt = function(x, ...){ 105 | check_installed("gt", reason="for function `as_gt()` to work.") 106 | UseMethod("as_gt") 107 | } 108 | 109 | 110 | #' Default method to convert an object to a `gt` table 111 | #' 112 | #' @param x object to be converted 113 | #' @param ... arguments for custom methods 114 | #' 115 | #' @describeIn as_gt default function 116 | #' 117 | #' @family as_gt methods 118 | #' @author Dan Chaltiel 119 | #' @export 120 | as_gt.default = function(x, ...){ 121 | gt::gt(data=x, ...) 122 | } 123 | -------------------------------------------------------------------------------- /R/methods.R: -------------------------------------------------------------------------------- 1 | 2 | utils::globalVariables(c(".id", "variable", "name")) 3 | 4 | # Utils ------------------------------------------------------------------- 5 | 6 | 7 | #' Test if an object is a crosstable 8 | #' 9 | #' @param x An object 10 | #' 11 | #' @return TRUE if the object inherits from the `crosstable` class or other subclasses. 12 | #' @export 13 | is.crosstable = function(x) { 14 | inherits(x, "crosstable") 15 | } 16 | 17 | #' @rdname is.crosstable 18 | #' @export 19 | is.transposed_crosstable = function(x) { 20 | inherits(x, "transposed_crosstable") 21 | } 22 | 23 | #' @rdname is.crosstable 24 | #' @export 25 | is.compacted_crosstable = function(x) { 26 | inherits(x, "compacted_crosstable") 27 | } 28 | 29 | #' @rdname is.crosstable 30 | #' @export 31 | is.multiby_crosstable = function(x) { 32 | inherits(x, "crosstable_multiby") 33 | } 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /R/reexport.R: -------------------------------------------------------------------------------- 1 | 2 | #' @importFrom dplyr %>% 3 | #' @export 4 | dplyr::`%>%` 5 | 6 | #' @importFrom dplyr everything 7 | #' @export 8 | dplyr::everything 9 | 10 | #' @importFrom dplyr all_of 11 | #' @export 12 | dplyr::all_of 13 | 14 | #' @importFrom dplyr any_of 15 | #' @export 16 | dplyr::any_of 17 | 18 | #' @importFrom dplyr starts_with 19 | #' @export 20 | dplyr::starts_with 21 | 22 | #' @importFrom dplyr ends_with 23 | #' @export 24 | dplyr::ends_with 25 | 26 | #' @importFrom dplyr contains 27 | #' @export 28 | dplyr::contains 29 | 30 | #' @importFrom dplyr matches 31 | #' @export 32 | dplyr::matches 33 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://danchaltiel.github.io/crosstable/ 2 | destination: docs 3 | 4 | 5 | home: 6 | title: An R package Crosstables for descriptive analyses 7 | description: Thoroughly describe all your datasets with useful metrics, using only a few lines of code. 8 | 9 | 10 | template: 11 | bootstrap: 5 12 | params: 13 | bootswatch: flatly 14 | opengraph: 15 | image: 16 | src: apple-touch-icon-180x180.png 17 | alt: "Crosstable: easy dataset description" 18 | twitter: 19 | creator: "@DanChaltiel" 20 | card: summary 21 | includes: 22 | in_header: | 23 | 24 | 25 | 31 | 32 | 33 | navbar: 34 | structure: 35 | left: [home, articles, reference, news] 36 | right: [docsearch, twitter, github] 37 | components: 38 | twitter: 39 | icon: "fab fa-twitter fa-lg" 40 | href: http://twitter.com/DanChaltiel 41 | articles: 42 | text: Articles 43 | menu: 44 | - text: Get started 45 | href: articles/crosstable.html 46 | - text: Select columns 47 | href: articles/crosstable-selection.html 48 | - text: Automatic reporting 49 | href: articles/crosstable-report.html 50 | - text: Using `percent_pattern` 51 | href: articles/percent_pattern.html 52 | 53 | 54 | articles: 55 | - title: Articles 56 | navbar: ~ 57 | contents: 58 | - crosstable 59 | - crosstable-selection 60 | - crosstable-report 61 | - percent_pattern 62 | 63 | 64 | reference: 65 | - title: "Main function" 66 | - contents: 67 | - crosstable 68 | - crosstable_options 69 | - crosstable_peek_options 70 | - crosstable_reset_options 71 | - title: "Datasets" 72 | desc: "Standard datasets, modified to have labels, characters, and factors" 73 | - contents: 74 | - iris2 75 | - mtcars2 76 | - title: "Labelling" 77 | desc: "Handle label attributes (compatible with Hmisc, expss, haven...)" 78 | - contents: 79 | - import_labels 80 | - set_label 81 | - get_label 82 | - remove_labels 83 | - apply_labels 84 | - rename_dataframe_with_labels 85 | - clean_names_with_labels 86 | - title: "Post-processing" 87 | desc: "Modify an already built crosstable" 88 | - contents: 89 | - transpose_crosstable 90 | - pivot_crosstable 91 | - title: "Summary functions" 92 | desc: "Summarise numeric variables" 93 | - contents: 94 | - summaryFunctions 95 | - cross_summary 96 | - na 97 | - "N" 98 | - title: "Visualization" 99 | desc: "Visualize a crosstable in various formats" 100 | - contents: 101 | - as_gt.crosstable 102 | - as_workbook 103 | - as_flextable 104 | - title: "Officer helpers" 105 | desc: "Used in cooperation with the `officer` package" 106 | - contents: 107 | - starts_with("body_") 108 | - docx_bookmarks2 109 | - write_and_open 110 | - generate_autofit_macro 111 | - title: "Utils" 112 | desc: "Practical functions for various purposes" 113 | - contents: 114 | - get_percent_pattern 115 | - format_fixed 116 | - compact 117 | - plim 118 | - confint_numeric 119 | - narm 120 | - is.crosstable 121 | - peek 122 | - title: "Effects and tests" 123 | - subtitle: "Default parameters" 124 | - contents: 125 | - crosstable_effect_args 126 | - crosstable_test_args 127 | - subtitle: "Effects" 128 | - contents: 129 | - display_effect 130 | - starts_with("effect_") 131 | - subtitle: "Tests" 132 | - contents: 133 | - display_test 134 | - starts_with("test_") 135 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | patch: 10 | default: 11 | target: auto 12 | threshold: 1% 13 | 14 | ignore: 15 | - "R/burgled.R" 16 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | 2 | ## Test environments 3 | 4 | * local R installation, R 4.4.1 5 | * GH Actions (instead of `check_rhub()`) 6 | * `check_win_devel()` 7 | 8 | 9 | ## R CMD check results 10 | 11 | No problem. 12 | 13 | -------------------------------------------------------------------------------- /crosstable.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: dce51297-d115-4c29-9607-26cedb2e94bf 3 | 4 | RestoreWorkspace: No 5 | SaveWorkspace: No 6 | AlwaysSaveHistory: Yes 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: Sweave 14 | LaTeX: pdfLaTeX 15 | 16 | AutoAppendNewline: Yes 17 | StripTrailingWhitespace: Yes 18 | LineEndingConversion: Posix 19 | 20 | BuildType: Package 21 | PackageUseDevtools: Yes 22 | PackageInstallArgs: --no-multiarch --with-keep.source 23 | PackageRoxygenize: rd,collate,namespace 24 | -------------------------------------------------------------------------------- /data-raw/iris2.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | iris2 = iris %>% 4 | expss::apply_labels( 5 | Species = "Specie", 6 | Sepal.Length = "Length of Sepal", 7 | Sepal.Width = "Width of Sepal", 8 | Petal.Length = "Length of Petal", 9 | Petal.Width = "Width of Petal" 10 | ) %>% 11 | as_tibble() 12 | 13 | usethis::use_data(iris2) 14 | -------------------------------------------------------------------------------- /data-raw/mtcars2.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | mtcars21 = mtcars %>% 4 | mutate(model=rownames(mtcars), 5 | vs=ifelse(vs==0, "vshaped", "straight"), 6 | am=ifelse(am==0, "auto", "manual"), 7 | across(c("cyl", "gear"), factor), 8 | .before=1) %>% 9 | expss::apply_labels( #I also could have used `Hmisc::label` 10 | model="Model", 11 | mpg="Miles/(US) gallon", 12 | cyl="Number of cylinders", 13 | disp="Displacement (cu.in.)", 14 | hp="Gross horsepower", 15 | drat="Rear axle ratio", 16 | wt="Weight (1000 lbs)", 17 | qsec="1/4 mile time", 18 | vs="Engine", 19 | am="Transmission", 20 | gear="Number of forward gears", 21 | carb="Number of carburetors" 22 | ) %>% 23 | mutate( 24 | hp_date = as.Date(hp , origin="2010-01-01") %>% set_label("Some nonsense date"), 25 | qsec_posix = as.POSIXct(qsec*3600*24 , origin="2010-01-01") %>% set_label("Date+time") 26 | ) %>% 27 | as_tibble() 28 | 29 | usethis::use_data(mtcars2, overwrite=TRUE) 30 | -------------------------------------------------------------------------------- /data/iris2.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/data/iris2.rda -------------------------------------------------------------------------------- /data/mtcars2.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/data/mtcars2.rda -------------------------------------------------------------------------------- /examples/example_doc.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/examples/example_doc.docx -------------------------------------------------------------------------------- /examples/result_test_crosstable_officer.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/examples/result_test_crosstable_officer.docx -------------------------------------------------------------------------------- /examples/test_legends_officer_v0.4.R: -------------------------------------------------------------------------------- 1 | 2 | #Located in examples/ 3 | 4 | 5 | 6 | 7 | 8 | # Officer v0.3 ------------------------------------------------------------ 9 | devtools::install_version("officer", "0.3.19") 10 | packageVersion("officer") 11 | 12 | # officer::styles_info(officer::read_docx()) %>% arrange(style_type) 13 | 14 | 15 | doc1 = read_docx() %>% 16 | body_add_title("Older officer versions", 1) %>% 17 | body_add_normal("Crosstable v{packageVersion('crosstable')}, officer v{packageVersion('officer')}.", 1) %>% 18 | body_add_normal("") %>% 19 | body_add_normal("As you can see in Tables \\@ref(tab1) and others, ", 20 | " and in Figures \\@ref(fig1) and others, ", 21 | "the iris dataset is about flowers.") %>% 22 | 23 | body_add_title("Tables", 2) %>% 24 | body_add_table_legend("default", bookmark="tab1") %>% 25 | body_add_table_legend("default == style=strong + legend_style=Normal", 26 | style="strong", 27 | legend_style="Normal") %>% 28 | body_add_table_legend("style=NULL, legend_style=Normal", 29 | style=NULL, 30 | legend_style="Normal") %>% 31 | body_add_table_legend("style=strong, legend_style=Table Caption", 32 | style="strong", 33 | legend_style="Table Caption") %>% 34 | body_add_table_legend("style=NULL, legend_style=centered", 35 | style=NULL, 36 | legend_style="centered") %>% 37 | body_add_table_legend("style=Titre2Car, legend_style=centered", 38 | style="Titre 2 Car", 39 | legend_style="centered") %>% 40 | 41 | 42 | body_add_title("Figures", 2) %>% 43 | body_add_figure_legend("default", bookmark="fig1") %>% 44 | body_add_figure_legend("default == style=strong + legend_style=Normal", 45 | style="strong", 46 | legend_style="Normal") %>% 47 | body_add_figure_legend("style=NULL, legend_style=Normal", 48 | style=NULL, 49 | legend_style="Normal") %>% 50 | body_add_figure_legend("style=strong, legend_style=Image Caption", 51 | style="strong", 52 | legend_style="Image Caption") %>% 53 | body_add_figure_legend("style=NULL, legend_style=centered", 54 | style=NULL, 55 | legend_style="centered") %>% 56 | body_add_figure_legend("style=Titre2Car, legend_style=centered", 57 | style="Titre 2 Car", 58 | legend_style="centered") %>% 59 | identity() 60 | 61 | # write_and_open(doc1) 62 | 63 | saveRDS(doc1, "examples/test_officer_v0.3.19_crosstable.rds") 64 | write_and_open(doc1, "examples/test_officer_v0.3.19_crosstable.docx") 65 | 66 | 67 | 68 | # Officer v0.4 ------------------------------------------------------------ 69 | 70 | install.packages("officer") #0.4+ 71 | packageVersion("officer") 72 | 73 | #"Table Caption" (default) style is bold italic 12 74 | fp = fp_text_lite(underlined=TRUE, font.size=15) 75 | fp2 = fp_text_lite(italic=TRUE, font.size=10) 76 | doc2 = read_docx() %>% 77 | # doc2 = readRDS("examples/test_officer_v0.3.19_crosstable.rds") %>% 78 | # body_add_break() %>% 79 | # body_add_title("Newer officer versions (v0.4+)", 1) %>% 80 | body_add_title("Crosstable v{packageVersion('crosstable')}, officer v{packageVersion('officer')}.", 1) %>% 81 | # body_add_normal("Crosstable v{packageVersion('crosstable')}, officer v{packageVersion('officer')}.", 1) %>% 82 | body_add_normal("") %>% 83 | body_add_normal("As you can see in Tables \\@ref(tab1), \\@ref(tab2) and others, ", 84 | " and in Figures \\@ref(fig1) and others, ", 85 | "the iris dataset is about flowers.") %>% 86 | body_add_normal("Note that the format in the text matches the format in `name_format`.") %>% 87 | body_add_normal("fp = underlined, size=15") %>% 88 | body_add_normal("fp2 = italic, size=9") %>% 89 | # body_add_list(c("fp = underlined, size=15", 90 | # "fp2 = italic, size=9")) %>% 91 | 92 | body_add_title("Tables", 2) %>% 93 | body_add_table_legend("default (legend_style=Normal, name_format=bold)", bookmark="tab1") %>% 94 | body_add_table_legend("legend_style=default (normal), name_format=fp", bookmark="tab2", 95 | name_format=fp) %>% 96 | body_add_table_legend("legend_style=default (normal), name_format=fp2", 97 | name_format=fp2) %>% 98 | body_add_table_legend("legend_style=centered, name_format=fp2", 99 | name_format=fp2, legend_style="centered") %>% 100 | body_add_table_legend("legend_style=Balloon Text, name_format=NULL", 101 | legend_style="Balloon Text") %>% 102 | body_add_table_legend("legacy: legend_style=Normal, style=strong", 103 | legacy=TRUE, style="strong", legend_style="Normal") %>% 104 | 105 | body_add_title("Figures", 2) %>% 106 | body_add_figure_legend("Legend of a figure", bookmark="fig1") %>% 107 | identity() 108 | 109 | # write_and_open(doc2) 110 | 111 | saveRDS(doc2, "examples/test_officer_v0.4_crosstable.rds") 112 | write_and_open(doc2, "examples/test_officer_v0.4_crosstable.docx") 113 | -------------------------------------------------------------------------------- /examples/test_officer_v0.3.19_crosstable.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/examples/test_officer_v0.3.19_crosstable.rds -------------------------------------------------------------------------------- /examples/test_officer_v0.4_crosstable.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/examples/test_officer_v0.4_crosstable.rds -------------------------------------------------------------------------------- /examples/vignette_markdown.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Iris" 3 | output: bookdown::word_document2 4 | output_file: "cross_markdown.docx" 5 | --- 6 | 7 | 8 | ```{r setup, include=FALSE} 9 | library(crosstable) 10 | library(flextable) 11 | library(dplyr) #pour le pipe %>% 12 | ``` 13 | 14 | Table iris is given in Table \@ref(tab:irisTable). 15 | 16 | ```{r description, echo=FALSE, results='asis'} 17 | cat(" (\\#tab:irisTable) Table Iris \n\r ") 18 | crosstable(iris, Sepal.Length, Sepal.Width, by=Species, test=TRUE, total="column") %>% as_flextable 19 | ``` -------------------------------------------------------------------------------- /examples/vignette_markdown.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/examples/vignette_markdown.docx -------------------------------------------------------------------------------- /examples/vignette_officer.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/examples/vignette_officer.docx -------------------------------------------------------------------------------- /inst/IMPORTLIST: -------------------------------------------------------------------------------- 1 | align = flextable 2 | attr = base 3 | bold = flextable 4 | colSums = base 5 | filter = dplyr 6 | fixed = stringr 7 | format = base 8 | gt = gt 9 | head = utils 10 | intersect = base 11 | isFALSE = base 12 | mean = base 13 | order = base 14 | print = base 15 | rowSums = base 16 | select = dplyr 17 | set_names = rlang 18 | setdiff = base 19 | summary = base 20 | t = base 21 | unname = base 22 | which = base 23 | writeLines = base 24 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | Acknowledgement 2 | Autofit 3 | Barnier's 4 | CMD 5 | Codecov 6 | Consolas 7 | CrosstableMacros 8 | Crosstables 9 | Ctrl 10 | Daus 11 | Deprecations 12 | FEXACT 13 | Flextables 14 | Github 15 | Gohel's 16 | Indice 17 | Julien 18 | Lifecycle 19 | NaNs 20 | ORCID 21 | POSIXt 22 | RStudio 23 | RStudio's 24 | Reimplement 25 | Rmarkdown 26 | Rmd 27 | StackOverflow 28 | Subheaders 29 | autocomplete 30 | autocompletion 31 | autofit 32 | autofitting 33 | behaviour 34 | bugfixes 35 | chisq 36 | ci 37 | conceptor 38 | conf 39 | confint 40 | copypasting 41 | customizable 42 | cy 43 | danchaltiel 44 | davidgohel 45 | docx 46 | expss 47 | flextable 48 | flextables 49 | fontsize 50 | ggplot 51 | github 52 | https 53 | io 54 | kbd 55 | kendall 56 | kruskal 57 | labelled 58 | logrank 59 | oducible 60 | oneway 61 | params 62 | pearson 63 | png 64 | ppi 65 | pre 66 | repr 67 | reprex 68 | reproducibility 69 | rmarkdown 70 | sd 71 | situ 72 | spearman 73 | stackoverflow 74 | subclasses 75 | syntaxes 76 | tibble 77 | tidyselect 78 | tidyverse 79 | unlabel 80 | -------------------------------------------------------------------------------- /inst/template_ls_sm.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/inst/template_ls_sm.docx -------------------------------------------------------------------------------- /man/apply_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.R 3 | \name{apply_labels} 4 | \alias{apply_labels} 5 | \title{Batch set variable labels} 6 | \usage{ 7 | apply_labels(data, ..., fn, warn_missing = FALSE) 8 | } 9 | \arguments{ 10 | \item{data}{data.frame/list} 11 | 12 | \item{...}{named arguments, as \code{colname="label"}} 13 | 14 | \item{fn}{alternatively, a function to be applied to all existing labels.} 15 | 16 | \item{warn_missing}{if TRUE, throw a warning if some names are missing} 17 | } 18 | \value{ 19 | An object of the same type as \code{data}, with labels 20 | } 21 | \description{ 22 | This function is a copycat of from expss package v0.10.7 (slightly modified) to avoid having to depend on expss. See \code{\link[expss:apply_labels]{expss::apply_labels()}} for more documentation. Note that this version is not compatible with \code{data.table}. 23 | } 24 | \examples{ 25 | iris \%>\% 26 | apply_labels(Sepal.Length="Length of Sepal", 27 | Sepal.Width="Width of Sepal") \%>\% 28 | crosstable() 29 | iris2 \%>\% 30 | apply_labels(fn=tolower) \%>\% 31 | crosstable() 32 | } 33 | \author{ 34 | Dan Chaltiel 35 | } 36 | -------------------------------------------------------------------------------- /man/as_flextable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/flextable.R 3 | \name{as_flextable.crosstable} 4 | \alias{as_flextable.crosstable} 5 | \alias{ctf} 6 | \alias{cross_to_flextable} 7 | \alias{to_flextable} 8 | \alias{as_flextable} 9 | \alias{af} 10 | \title{Turns a \code{crosstable} object into a formatted \code{flextable}} 11 | \usage{ 12 | \method{as_flextable}{crosstable}( 13 | x, 14 | keep_id = FALSE, 15 | by_header = NULL, 16 | autofit = TRUE, 17 | compact = FALSE, 18 | show_test_name = TRUE, 19 | fontsizes = list(body = 11, subheaders = 11, header = 11), 20 | padding_v = NULL, 21 | remove_header_keys = TRUE, 22 | header_show_n = FALSE, 23 | header_show_n_pattern = "{.col} (N={.n})", 24 | generic_labels = list(id = ".id", variable = "variable", value = "value", total = 25 | "Total", label = "label", test = "test", effect = "effect"), 26 | ... 27 | ) 28 | 29 | as_flextable(x, ...) 30 | } 31 | \arguments{ 32 | \item{x}{the result of \code{\link[=crosstable]{crosstable()}}.} 33 | 34 | \item{keep_id}{whether to keep the \code{.id} column.} 35 | 36 | \item{by_header}{a string to override the header if \code{x} has only one \code{by} stratum.} 37 | 38 | \item{autofit}{whether to automatically adjust the table. Can also be a function.} 39 | 40 | \item{compact}{whether to compact the table. If \code{TRUE}, see \code{\link[=ct_compact.crosstable]{ct_compact.crosstable()}} to see how to use \code{keep_id}.} 41 | 42 | \item{show_test_name}{in the \code{test} column, show the test name.} 43 | 44 | \item{fontsizes}{font sizes as a list of keys. Default to \code{list(body=11, subheaders=11, header=11)}. If set through arguments instead of options, all 3 names should be specified.} 45 | 46 | \item{padding_v}{vertical padding (body).} 47 | 48 | \item{remove_header_keys}{if \code{TRUE} and \code{x} has several \code{by} strata, header will only display values.} 49 | 50 | \item{header_show_n}{numeric vector telling on which depth the group size should be indicated in the header. You can control the pattern using option \code{crosstable_options}. See \code{\link[=crosstable_options]{crosstable_options()}} for details about it. See example for use case.} 51 | 52 | \item{header_show_n_pattern}{glue pattern used when \code{header_show_n==TRUE}. \code{.col} is the name of the column and \code{.n} the size of the group. Default to \code{{.col} (N={.n})}; you can also use \code{{.col_key}} and \code{{.col_val}} when \code{by} has multiple stratum. To control the "Total" column, enter this as a \code{list} with names "cell" and "total".} 53 | 54 | \item{generic_labels}{names of the crosstable default columns. Useful for translation for instance.} 55 | 56 | \item{...}{unused.} 57 | } 58 | \value{ 59 | a flextable. 60 | } 61 | \description{ 62 | Turns a \code{crosstable} object into a formatted \code{flextable} 63 | } 64 | \section{Methods (by class)}{ 65 | \itemize{ 66 | \item \code{as_flextable(crosstable)}: Turns a \code{crosstable} object into a formatted \code{flextable}. 67 | 68 | }} 69 | \examples{ 70 | crosstable_options(crosstable_fontsize_header=14, 71 | crosstable_fontsize_subheaders=10, 72 | crosstable_fontsize_body=8) 73 | crosstable(iris) \%>\% as_flextable() 74 | crosstable(mtcars2, -model, by=c(am, vs)) \%>\% as_flextable(header_show_n=1) 75 | crosstable(mtcars2, cols=c(mpg, cyl), by=am, effect=TRUE) \%>\% 76 | as_flextable(keep_id=TRUE, autofit=FALSE) 77 | crosstable(mtcars2, cols=c(mpg, cyl), by=am, effect=TRUE, total=TRUE) \%>\% 78 | as_flextable(compact=TRUE, header_show_n=TRUE, 79 | header_show_n_pattern=list(cell="{.col} (N={.n})", total="Total\n(N={.n})")) 80 | 81 | #Renaming (because why not?) 82 | crosstable(mtcars2, am, by=vs, total="both", test=TRUE, effect=TRUE) \%>\% 83 | dplyr::rename(ID=.id, math=variable, Tot=Total, lab=label, pval=test, fx=effect) \%>\% 84 | as_flextable(by_header = "Engine shape", 85 | generic_labels=list(id = "ID", variable = "math", total="Tot", 86 | label = "lab", test = "pval", effect="fx")) 87 | } 88 | \seealso{ 89 | \code{\link[=crosstable]{crosstable()}}, \code{\link[flextable:flextable]{flextable::flextable()}}, \code{\link[=as_gt.crosstable]{as_gt.crosstable()}} 90 | } 91 | \author{ 92 | Dan Chaltiel 93 | } 94 | -------------------------------------------------------------------------------- /man/as_gt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/gt.R 3 | \name{as_gt.crosstable} 4 | \alias{as_gt.crosstable} 5 | \alias{as_gt} 6 | \alias{as_gt.default} 7 | \title{Converts a \code{crosstable} object into a formatted \code{gt} table.} 8 | \usage{ 9 | \method{as_gt}{crosstable}( 10 | x, 11 | show_test_name = TRUE, 12 | by_header = NULL, 13 | keep_id = FALSE, 14 | generic_labels = list(id = ".id", variable = "variable", value = "value", total = 15 | "Total", label = "label", test = "test", effect = "effect"), 16 | ... 17 | ) 18 | 19 | as_gt(x, ...) 20 | 21 | \method{as_gt}{default}(x, ...) 22 | } 23 | \arguments{ 24 | \item{x}{object to be converted} 25 | 26 | \item{show_test_name}{in the \code{test} column, show the test name} 27 | 28 | \item{by_header}{a string to override the \code{by} header} 29 | 30 | \item{keep_id}{whether to keep the \code{.id} column} 31 | 32 | \item{generic_labels}{names of the crosstable default columns} 33 | 34 | \item{...}{arguments for custom methods} 35 | } 36 | \value{ 37 | a formatted \code{gt} table 38 | } 39 | \description{ 40 | Converts a \code{crosstable} object into a formatted \code{gt} table. 41 | 42 | Method to convert an object to a \code{gt} table 43 | 44 | Default method to convert an object to a \code{gt} table 45 | } 46 | \section{Methods (by class)}{ 47 | \itemize{ 48 | \item \code{as_gt(crosstable)}: For crosstables 49 | 50 | \item \code{as_gt(default)}: default function 51 | 52 | }} 53 | \examples{ 54 | xx = mtcars2 \%>\% dplyr::select(2:10) 55 | crosstable(xx) \%>\% as_gt 56 | crosstable(xx, by=am) \%>\% as_gt 57 | crosstable(xx, by=cyl, test=TRUE, total=TRUE) \%>\% 58 | as_gt(keep_id=TRUE, show_test_name=FALSE, by_header="Cylinders") 59 | } 60 | \seealso{ 61 | \code{\link[=as_flextable.crosstable]{as_flextable.crosstable()}} 62 | 63 | \code{\link[gt:gt]{gt::gt()}} 64 | } 65 | \author{ 66 | Dan Chaltiel 67 | } 68 | \concept{as_gt methods} 69 | -------------------------------------------------------------------------------- /man/as_workbook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openxlsx.R 3 | \name{as_workbook} 4 | \alias{as_workbook} 5 | \title{Converts a \code{crosstable} object into a formatted, savable \code{openxlsx} workbook.} 6 | \usage{ 7 | as_workbook( 8 | x, 9 | show_test_name = TRUE, 10 | by_header = NULL, 11 | keep_id = FALSE, 12 | generic_labels = list(id = ".id", variable = "variable", value = "value", total = 13 | "Total", label = "label", test = "test", effect = "effect"), 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{x}{the result of \code{\link[=crosstable]{crosstable()}} or a list of crosstables} 19 | 20 | \item{show_test_name}{in the \code{test} column, show the test name} 21 | 22 | \item{by_header}{a string to override the \code{by} header} 23 | 24 | \item{keep_id}{whether to keep the \code{.id} column} 25 | 26 | \item{generic_labels}{names of the crosstable default columns} 27 | 28 | \item{...}{unused} 29 | } 30 | \value{ 31 | an \code{openxlsx} workbook containing the crosstable(s) 32 | } 33 | \description{ 34 | Converts a \code{crosstable} object into a formatted, savable \code{openxlsx} workbook. 35 | } 36 | \examples{ 37 | library(openxlsx) 38 | target = tempfile(fileext=".xlsx") 39 | 40 | x=crosstable(mtcars2, c(mpg, vs, gear), total=TRUE, test=TRUE) 41 | as_workbook(x, keep_id=TRUE) \%>\% 42 | saveWorkbook(file=target) 43 | if(interactive()) browseURL(target) 44 | 45 | target = tempfile(fileext=".xlsx") 46 | x2=list(iris=crosstable(iris2), crosstable(mtcars2)) 47 | as_workbook(x2, keep_id=TRUE) \%>\% 48 | saveWorkbook(file=target) 49 | if(interactive()) browseURL(target) 50 | } 51 | \author{ 52 | Dan Chaltiel 53 | } 54 | -------------------------------------------------------------------------------- /man/body_add_crosstable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_crosstable} 4 | \alias{body_add_crosstable} 5 | \title{Add a crosstable to an \code{officer} document} 6 | \usage{ 7 | body_add_crosstable( 8 | doc, 9 | x, 10 | body_fontsize = NULL, 11 | header_fontsize = ceiling(body_fontsize * 1.2), 12 | padding_v = NULL, 13 | allow_break = TRUE, 14 | max_cols = 25, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{doc}{a \code{rdocx} object, created by \code{\link[officer:read_docx]{officer::read_docx()}}} 20 | 21 | \item{x}{a \code{crosstable} object} 22 | 23 | \item{body_fontsize}{fontsize of the body} 24 | 25 | \item{header_fontsize}{fontsize of the header. Defaults to \code{1.2*body_fontsize}.} 26 | 27 | \item{padding_v}{vertical padding of all table rows} 28 | 29 | \item{allow_break}{allow crosstable rows to break across pages} 30 | 31 | \item{max_cols}{max number of columns for \code{x}} 32 | 33 | \item{...}{further arguments passed to \code{\link[=as_flextable.crosstable]{as_flextable.crosstable()}}} 34 | } 35 | \value{ 36 | The docx object \code{doc} 37 | } 38 | \description{ 39 | \code{\link[=body_add_crosstable]{body_add_crosstable()}} adds such a \code{flextable} an \code{officer} document. 40 | } 41 | \examples{ 42 | #Officer 43 | library(officer) 44 | mytable = crosstable(mtcars2) 45 | doc = read_docx() \%>\% 46 | body_add_crosstable(mytable) \%>\% 47 | body_add_break \%>\% 48 | body_add_crosstable(mytable, compact=TRUE) 49 | 50 | dfile = tempfile(fileext=".docx") 51 | print(doc, target = dfile) 52 | if(interactive()) browseURL(dfile) 53 | } 54 | \author{ 55 | Dan Chaltiel 56 | } 57 | -------------------------------------------------------------------------------- /man/body_add_crosstable_footnote.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_crosstable_footnote} 4 | \alias{body_add_crosstable_footnote} 5 | \title{Adds a standard footnote explaining the abbreviations used in a crosstable} 6 | \usage{ 7 | body_add_crosstable_footnote(doc) 8 | } 9 | \arguments{ 10 | \item{doc}{a \code{rdocx} object} 11 | } 12 | \value{ 13 | The docx object \code{doc} 14 | } 15 | \description{ 16 | Use it below \code{\link[=body_add_crosstable]{body_add_crosstable()}}. 17 | Footnote: Med: median, IQR: interquartile range, Std: standard deviation. Percentages are expressed in column. 18 | } 19 | \author{ 20 | Dan Chaltiel 21 | } 22 | -------------------------------------------------------------------------------- /man/body_add_gg2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_gg2} 4 | \alias{body_add_gg2} 5 | \title{Alternative to \code{\link[officer:body_add_gg]{officer::body_add_gg()}} which uses \code{ggplot} syntax} 6 | \usage{ 7 | body_add_gg2( 8 | doc, 9 | value, 10 | width = getOption("crosstable_gg_width", 6), 11 | height = getOption("crosstable_gg_height", 5), 12 | units = getOption("crosstable_units", "in"), 13 | style = getOption("crosstable_style_image", doc$default_styles$paragraph), 14 | res = 300, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{doc}{an \code{rdocx} object} 20 | 21 | \item{value}{ggplot object} 22 | 23 | \item{width, height}{width and height. Can be abbreviated to w and h.} 24 | 25 | \item{units}{units for width and height} 26 | 27 | \item{style}{paragraph style} 28 | 29 | \item{res}{resolution of the png image in ppi (passed to the argument \code{dpi} of \code{\link[ggplot2:ggsave]{ggplot2::ggsave()}})} 30 | 31 | \item{...}{other arguments to be passed to \code{\link[ggplot2:ggsave]{ggplot2::ggsave()}}} 32 | } 33 | \value{ 34 | The docx object \code{doc} 35 | } 36 | \description{ 37 | Alternative to \code{\link[officer:body_add_gg]{officer::body_add_gg()}} which uses \code{ggplot} syntax 38 | } 39 | \examples{ 40 | library(officer) 41 | library(ggplot2) 42 | p = ggplot(data=iris, aes(Sepal.Length, Petal.Length)) + geom_point() 43 | crosstable_options( 44 | units="cm", 45 | style_image="centered" 46 | ) 47 | doc = read_docx() \%>\% 48 | body_add_normal("Text before") \%>\% 49 | body_add_gg2(p, w=14, h=10, scale=1.5) \%>\% #or units="cm" instead of using options 50 | body_add_normal("Text after") 51 | write_and_open(doc) 52 | } 53 | \author{ 54 | Dan Chaltiel 55 | } 56 | -------------------------------------------------------------------------------- /man/body_add_img2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_img2} 4 | \alias{body_add_img2} 5 | \title{Alternative to \code{\link[officer:body_add_img]{officer::body_add_img()}} which adds a \code{units} choice} 6 | \usage{ 7 | body_add_img2( 8 | doc, 9 | src, 10 | width, 11 | height, 12 | units = getOption("crosstable_units", "in"), 13 | style = getOption("crosstable_style_image", doc$default_styles$paragraph), 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{doc}{an \code{rdocx} object} 19 | 20 | \item{src}{image filename, the basename of the file must not contain any blank.} 21 | 22 | \item{width, height}{width and height. Can be abbreviated to w and h.} 23 | 24 | \item{units}{units for width and height} 25 | 26 | \item{style}{paragraph style} 27 | 28 | \item{...}{other arguments to be passed to \code{\link[officer:body_add_img]{officer::body_add_img()}}} 29 | } 30 | \value{ 31 | The docx object \code{doc} 32 | } 33 | \description{ 34 | Alternative to \code{\link[officer:body_add_img]{officer::body_add_img()}} which adds a \code{units} choice 35 | } 36 | \examples{ 37 | img.file = file.path( R.home("doc"), "html", "logo.jpg" ) 38 | if(file.exists(img.file)){ 39 | library(officer) 40 | options(crosstable_units="cm") 41 | doc = read_docx() \%>\% 42 | body_add_normal("This is the R logo.") \%>\% 43 | body_add_img2(img.file, h=7.6, w=10, style="centered") #or units="cm" without options 44 | #write_and_open(doc) 45 | } 46 | } 47 | \seealso{ 48 | \code{\link[=body_add_gg2]{body_add_gg2()}} 49 | } 50 | \author{ 51 | Dan Chaltiel 52 | } 53 | -------------------------------------------------------------------------------- /man/body_add_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_list} 4 | \alias{body_add_list} 5 | \alias{body_add_list_item} 6 | \title{Add a list to an \code{officer} document} 7 | \usage{ 8 | body_add_list(doc, value, ordered = FALSE, style = NULL, ...) 9 | 10 | body_add_list_item(doc, value, ordered = FALSE, style = NULL, ...) 11 | } 12 | \arguments{ 13 | \item{doc}{a docx object} 14 | 15 | \item{value}{a character vector (\code{body_add_list()}) or scalar (\code{body_add_list_item}). See Section below for markdown support.} 16 | 17 | \item{ordered}{if \code{TRUE}, adds an ordered list, if \code{FALSE} (default), adds a bullet list} 18 | 19 | \item{style}{specify the style manually, overriding \code{ordered}. A better way is to set options \code{crosstable_style_list_ordered} and \code{crosstable_style_list_unordered} globally.} 20 | 21 | \item{...}{passed on to \code{\link[officer:body_add_par]{officer::body_add_par()}}} 22 | } 23 | \value{ 24 | The docx object \code{doc} 25 | } 26 | \description{ 27 | Add a list to an \code{officer} document 28 | } 29 | \details{ 30 | Ordered lists and bullet lists are not supported by the default officer template (see \href{#262}{https://github.com/davidgohel/officer/issues/262}). You have to manually set custom styles matching those list in a custom Word template file. Then, you can use either the \code{style} argument or crosstable options. See examples for more details. 31 | } 32 | \section{Markdown support}{ 33 | 34 | In all \code{crosstable} helpers for \code{officer}, you can use the following Markdown syntax to format your text: 35 | \itemize{ 36 | \item \emph{bold}: \code{"**text in bold**"} 37 | \item *italics: \code{"*text in italics*"} 38 | \item \emph{subscript}: \code{"Text in ~subscript~"} 39 | \item \emph{superscript}: \code{"Text in ^superscript^"} 40 | \item \emph{newline}: \verb{Before
After} 41 | \item \emph{color}: \code{"red text"} 42 | \item \emph{shade}: \code{"yellow text"} (background color) 43 | \item \emph{font family}: \code{"symbol"} ( 44 | } 45 | 46 | Note that the font name depends on your system language. For instant, in French, it would be \code{Symbol} with an uppercase first letter. 47 | 48 | See the last example of \code{\link[=body_add_normal]{body_add_normal()}} for a practical case. 49 | } 50 | 51 | \examples{ 52 | \dontrun{ 53 | #For this example to work, `my_template.docx` should include styles named 54 | #`ordered_list` and `unordered_list` 55 | 56 | library(officer) 57 | library(crosstable) 58 | options(crosstable_style_list_ordered="ordered_list") 59 | options(crosstable_style_list_unordered="unordered_list") 60 | 61 | read_docx("my_template.docx") \%>\% 62 | body_add_list(c("Numbered item 1", "Numbered item 2"), ordered = TRUE) \%>\% 63 | body_add_list_item("Numbered item 3", ordered = TRUE) \%>\% 64 | body_add_list(c("Bullet item 1", "Bullet item 2"), ordered = FALSE) \%>\% 65 | body_add_list_item("Bullet item 3", ordered = FALSE) \%>\% 66 | write_and_open() 67 | } 68 | } 69 | \author{ 70 | Dan Chaltiel 71 | } 72 | -------------------------------------------------------------------------------- /man/body_add_normal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_normal} 4 | \alias{body_add_normal} 5 | \alias{body_add_glued} 6 | \title{Add a new paragraph with default style} 7 | \usage{ 8 | body_add_normal( 9 | doc, 10 | ..., 11 | .sep = "", 12 | style = NULL, 13 | squish = TRUE, 14 | font_size = NA, 15 | envir = parent.frame(), 16 | parse = c("ref", "format", "code") 17 | ) 18 | } 19 | \arguments{ 20 | \item{doc}{the doc object (created with the \code{read_docx} function of \code{officer} package)} 21 | 22 | \item{...}{one or several character strings, pasted using \code{.sep}. As with \code{glue::glue()}, expressions enclosed by braces will be evaluated as R code. If more than one variable is passed, all should be of length 1.} 23 | 24 | \item{.sep}{Separator used to separate elements.} 25 | 26 | \item{style}{Style for normal text. Best set with \code{\link[=crosstable_options]{crosstable_options()}}.} 27 | 28 | \item{squish}{Whether to squish the result (remove trailing and repeated spaces). Default to \code{TRUE}. Allows to add multiline paragraph without breaking the string.} 29 | 30 | \item{font_size}{Font size.} 31 | 32 | \item{envir}{Environment to evaluate each expression in \code{glue()}.} 33 | 34 | \item{parse}{which format to parse. Default to all formats (\code{c("ref", "format", "code")}).} 35 | } 36 | \value{ 37 | a new doc object 38 | 39 | The docx object \code{doc} 40 | } 41 | \description{ 42 | Add a new paragraph in an \code{officer} document with default style.\cr 43 | Variables can be inserted in the text as multiple strings (\code{paste()} style) or enclosed by braces (\code{glue()} style). \cr 44 | Basic markdown syntax is available: \verb{**bold**}, \verb{*italic*}, and \verb{_underlined_}. \cr 45 | References to any bookmark can be inserted using the syntax \verb{@ref(bookmark)} and newlines can be inserted using the token \verb{
}. 46 | } 47 | \section{Markdown support}{ 48 | 49 | In all \code{crosstable} helpers for \code{officer}, you can use the following Markdown syntax to format your text: 50 | \itemize{ 51 | \item \emph{bold}: \code{"**text in bold**"} 52 | \item *italics: \code{"*text in italics*"} 53 | \item \emph{subscript}: \code{"Text in ~subscript~"} 54 | \item \emph{superscript}: \code{"Text in ^superscript^"} 55 | \item \emph{newline}: \verb{Before
After} 56 | \item \emph{color}: \code{"red text"} 57 | \item \emph{shade}: \code{"yellow text"} (background color) 58 | \item \emph{font family}: \code{"symbol"} ( 59 | } 60 | 61 | Note that the font name depends on your system language. For instant, in French, it would be \code{Symbol} with an uppercase first letter. 62 | 63 | See the last example of \code{\link[=body_add_normal]{body_add_normal()}} for a practical case. 64 | } 65 | 66 | \examples{ 67 | library(officer) 68 | library(crosstable) 69 | 70 | info_rows = c("Also, table iris has {nrow(iris)} rows.", 71 | "And table mtcars has {nrow(mtcars)} rows.") 72 | doc = read_docx() \%>\% 73 | body_add_normal("Table iris has", ncol(iris), "columns.", .sep=" ") \%>\% #paste style 74 | body_add_normal("However, table mtcars has {ncol(mtcars)} columns") \%>\% #glue style 75 | body_add_normal(info_rows) \%>\% #vector style 76 | body_add_normal("") 77 | doc = doc \%>\% 78 | body_add_normal("You can write text in *italic1*, _underlined1_, **bold1**, and `code`, 79 | and you can also add * **references** *, for instance a ref to Table 80 | @ref(my_table). Multiple spaces are ignored (squished) so that you 81 | can enter multiline text.") \%>\% 82 | body_add_normal() \%>\% 83 | body_add_normal("Here I should use `body_add_crosstable()` to add a table before the 84 | legend.") \%>\% 85 | body_add_table_legend("My pretty table", bookmark="my_table") 86 | write_and_open(doc) 87 | 88 | #Markdown support 89 | read_docx() \%>\% 90 | body_add_normal("This is **bold and *italic* (see Table @ref(my_bkm)). **
This is 91 | **bold `console \\\\*CODE\\\\*` and *bold _and_ italic* **") \%>\% 92 | body_add_normal("This is red **bold** text, this is ~subscript *italic*~, 93 | and this is ^superscript with yellow^") \%>\% 94 | body_add_normal("This is a fancy font and this `is code`!!") \%>\% 95 | #you might need to change "Alibi" to "alibi" here 96 | body_add_normal() \%>\% 97 | body_add_table_legend("Some table legend", bookmark="my_bkm") \%>\% 98 | write_and_open() 99 | } 100 | \author{ 101 | Dan Chaltiel 102 | } 103 | -------------------------------------------------------------------------------- /man/body_add_table_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_table_list} 4 | \alias{body_add_table_list} 5 | \alias{body_add_flextable_list} 6 | \alias{body_add_crosstable_list} 7 | \title{Add a list of tables} 8 | \usage{ 9 | body_add_table_list( 10 | doc, 11 | l, 12 | fun_before = "title2", 13 | fun_after = NULL, 14 | fun = fun_before, 15 | ... 16 | ) 17 | 18 | body_add_flextable_list(...) 19 | 20 | body_add_crosstable_list(...) 21 | } 22 | \arguments{ 23 | \item{doc}{a \code{rdocx} object, created by \code{\link[officer:read_docx]{officer::read_docx()}}} 24 | 25 | \item{l}{a named list of tables (of class \code{crosstable}, \code{flextable}, or \code{data.frame}).} 26 | 27 | \item{fun_before}{a function to be used before each table} 28 | 29 | \item{fun_after}{a function to be used after each table.} 30 | 31 | \item{fun}{Deprecated} 32 | 33 | \item{...}{arguments passed on to \code{\link[=body_add_crosstable]{body_add_crosstable()}} or \code{\link[flextable:body_add_flextable]{flextable::body_add_flextable()}}} 34 | } 35 | \value{ 36 | The docx object \code{doc} 37 | } 38 | \description{ 39 | Add a list of tables in an officer document. \code{crosstables} will be added using \code{\link[=body_add_crosstable]{body_add_crosstable()}} and \code{flextables} will be added using \code{\link[flextable:body_add_flextable]{flextable::body_add_flextable()}}. Plain dataframes will be converted to flextables. 40 | } 41 | \section{\code{fun_before} and \code{fun_after}}{ 42 | 43 | These should be function of the form \verb{function(doc, .name)} where \code{.name} is the name of the current table of the list. 44 | You can also pass \code{"title2"} to add the name as a title of level 2 between each table (works for levels 3 and 4 as well), \code{"newline"} to simply add a new line, or even \code{NULL} to not separate them (beware that the tables might merge then). 45 | \code{fun_before} is designed to add a title while \code{fun_after} is designed to add a table legend (cf. examples). 46 | } 47 | 48 | \examples{ 49 | library(officer) 50 | ctl = list(iris2=crosstable(iris2, 1), 51 | "Just a flextable"=flextable::flextable(mtcars2[1:5,1:5]), 52 | "Just a dataframe"=iris2[1:5,1:5]) 53 | 54 | fun1 = function(doc, .name){ 55 | doc \%>\% 56 | body_add_title(" This is table '{.name}' as a flex/crosstable", level=2) \%>\% 57 | body_add_normal("Here is the table:") 58 | } 59 | fun2 = function(doc, .name){ 60 | doc \%>\% body_add_table_legend("{.name}", bookmark=.name) 61 | } 62 | read_docx() \%>\% 63 | body_add_title("Separated by subtitle", 1) \%>\% 64 | body_add_table_list(ctl, fun_before="title2") \%>\% 65 | body_add_break() \%>\% 66 | body_add_title("Separated using a custom function", 1) \%>\% 67 | body_add_normal("You can therefore use bookmarks, for instance here are 68 | tables \\\\@ref(iris2), \\\\@ref(just_a_flextable) 69 | and \\\\@ref(just_a_dataframe).") \%>\% 70 | body_add_table_list(ctl, fun_before=fun1, fun_after=fun2, body_fontsize=8) \%>\% 71 | write_and_open() 72 | } 73 | -------------------------------------------------------------------------------- /man/body_add_table_section.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_table_section} 4 | \alias{body_add_table_section} 5 | \title{Add a section with a table and its legend} 6 | \usage{ 7 | body_add_table_section( 8 | doc, 9 | x, 10 | legend, 11 | ..., 12 | bookmark = NULL, 13 | title = getOption("crosstable_section_title", TRUE), 14 | title_lvl = getOption("crosstable_section_title_level", 3), 15 | sentence = getOption("crosstable_section_sentence", FALSE) 16 | ) 17 | } 18 | \arguments{ 19 | \item{doc}{a \code{rdocx} object} 20 | 21 | \item{x}{a table: \code{crosstable}, \code{flextable}, or plain old \code{dataframe}} 22 | 23 | \item{legend}{the legend to use} 24 | 25 | \item{...}{passed on to \code{\link[flextable:body_add_flextable]{flextable::body_add_flextable()}} or \code{\link[=body_add_crosstable]{body_add_crosstable()}}} 26 | 27 | \item{bookmark}{the bookmark to use. Defaults to the cleaned variable name of \code{x}} 28 | 29 | \item{title}{the title to add for the section. Can also be \code{FALSE} (no title) or \code{TRUE} (the title defaults to \code{legend})} 30 | 31 | \item{title_lvl}{the title level if applicable} 32 | 33 | \item{sentence}{a sentence to add between the title (if applicable) and the table. If \code{TRUE}, defaults to \code{"Information about {tolower(title)} is described in Table @ref({bookmark})"}.} 34 | } 35 | \value{ 36 | The \code{docx} object \code{doc} 37 | } 38 | \description{ 39 | Add a section with a table and its legend 40 | } 41 | \examples{ 42 | library(officer) 43 | read_docx() \%>\% 44 | body_add_title("Description", 1) \%>\% 45 | body_add_title("Population A", 2) \%>\% 46 | body_add_table_section(head(iris), "The iris dataset", sentence=TRUE) \%>\% 47 | body_add_table_section(crosstable(iris), "A crosstable of the iris dataset", 48 | title=FALSE, sentence=TRUE, body_fontsize=8) \%>\% 49 | write_and_open() 50 | } 51 | -------------------------------------------------------------------------------- /man/body_add_title.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_add_title} 4 | \alias{body_add_title} 5 | \title{Add a title to an \code{officer} document} 6 | \usage{ 7 | body_add_title( 8 | doc, 9 | value, 10 | level = 1, 11 | squish = TRUE, 12 | envir = parent.frame(), 13 | style = getOption("crosstable_style_heading", "heading") 14 | ) 15 | } 16 | \arguments{ 17 | \item{doc}{the doc object (created with the \code{read_docx} function of \code{officer} package)} 18 | 19 | \item{value}{a character string. See Section below for markdown support.} 20 | 21 | \item{level}{the level of the title. See \code{styles_info(doc)} to know the possibilities.} 22 | 23 | \item{squish}{Whether to squish the result (remove trailing and repeated spaces). Default to \code{TRUE}.} 24 | 25 | \item{envir}{Environment to evaluate each expression in \code{glue()}.} 26 | 27 | \item{style}{the name of the title style. See \code{styles_info(doc)} to know the possibilities.} 28 | } 29 | \value{ 30 | The docx object \code{doc} 31 | } 32 | \description{ 33 | Add a title to an \code{officer} document 34 | } 35 | \section{Markdown support}{ 36 | 37 | In all \code{crosstable} helpers for \code{officer}, you can use the following Markdown syntax to format your text: 38 | \itemize{ 39 | \item \emph{bold}: \code{"**text in bold**"} 40 | \item *italics: \code{"*text in italics*"} 41 | \item \emph{subscript}: \code{"Text in ~subscript~"} 42 | \item \emph{superscript}: \code{"Text in ^superscript^"} 43 | \item \emph{newline}: \verb{Before
After} 44 | \item \emph{color}: \code{"red text"} 45 | \item \emph{shade}: \code{"yellow text"} (background color) 46 | \item \emph{font family}: \code{"symbol"} ( 47 | } 48 | 49 | Note that the font name depends on your system language. For instant, in French, it would be \code{Symbol} with an uppercase first letter. 50 | 51 | See the last example of \code{\link[=body_add_normal]{body_add_normal()}} for a practical case. 52 | } 53 | 54 | \examples{ 55 | library(officer) 56 | library(crosstable) 57 | library(dplyr) 58 | doc = read_docx() \%>\% 59 | body_add_title("La table iris (nrow={nrow(iris)})", 1) \%>\% 60 | body_add_title("Description", 2) \%>\% 61 | body_add_normal("La table iris a ", ncol(iris), " colonnes.") 62 | #write_and_open(doc) 63 | } 64 | \author{ 65 | Dan Chaltiel 66 | } 67 | -------------------------------------------------------------------------------- /man/body_replace_text_at_bkms.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{body_replace_text_at_bkms} 4 | \alias{body_replace_text_at_bkms} 5 | \title{Replace text on several bookmarks at once} 6 | \usage{ 7 | body_replace_text_at_bkms(doc, ..., envir = parent.frame()) 8 | } 9 | \arguments{ 10 | \item{doc}{a \code{rdocx} object} 11 | 12 | \item{...}{named} 13 | 14 | \item{envir}{Environment to evaluate each expression in \code{glue()}.} 15 | } 16 | \value{ 17 | The docx object \code{doc} 18 | } 19 | \description{ 20 | Replace text on several bookmarks at once 21 | } 22 | \author{ 23 | Dan Chaltiel 24 | } 25 | -------------------------------------------------------------------------------- /man/clean_names_with_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.R 3 | \name{clean_names_with_labels} 4 | \alias{clean_names_with_labels} 5 | \title{Cleans names of a dataframe while retaining old names as labels} 6 | \usage{ 7 | clean_names_with_labels( 8 | df, 9 | except = NULL, 10 | .fun = getOption("crosstable_clean_names_fun") 11 | ) 12 | } 13 | \arguments{ 14 | \item{df}{a data.frame} 15 | 16 | \item{except}{<\code{\link[tidyselect:language]{tidy-select}}> columns that should not be renamed.} 17 | 18 | \item{.fun}{the function used to clean the names. Default function is limited; if the cleaning is not good enough you could use janitor::make_clean_names()} 19 | } 20 | \value{ 21 | A dataframe with clean names and label attributes 22 | } 23 | \description{ 24 | Cleans names of a dataframe while retaining old names as labels 25 | } 26 | \examples{ 27 | #options(crosstable_clean_names_fun=janitor::make_clean_names) 28 | x = data.frame("name with space"=1, TwoWords=1, "total $ (2009)"=1, àccénts=1, 29 | check.names=FALSE) 30 | cleaned = clean_names_with_labels(x, except=TwoWords) 31 | cleaned \%>\% names() 32 | cleaned \%>\% get_label() 33 | } 34 | \author{ 35 | Dan Chaltiel 36 | } 37 | -------------------------------------------------------------------------------- /man/confint_numeric.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{confint_numeric} 4 | \alias{confint_numeric} 5 | \title{Confidence interval of a numeric vector} 6 | \usage{ 7 | confint_numeric(object, level = 0.95, B = 0) 8 | } 9 | \arguments{ 10 | \item{object}{a vector, numeric or equivalent (date, logical...)} 11 | 12 | \item{level}{the confidence level required} 13 | 14 | \item{B}{if >0, the number of bootstraps} 15 | } 16 | \value{ 17 | the vector [conf_inf, conf_sup] 18 | } 19 | \description{ 20 | Not an S3 method, which might have conflicted with \link[stats:confint]{stats::confint}. 21 | } 22 | \examples{ 23 | confint_numeric(iris$Sepal.Length) 24 | confint_numeric(mtcars2$hp_date) 25 | confint_numeric(mtcars2$hp_date, level=0.99) 26 | } 27 | \author{ 28 | Dan Chaltiel 29 | } 30 | -------------------------------------------------------------------------------- /man/cross_summary.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/funs.R 3 | \name{cross_summary} 4 | \alias{cross_summary} 5 | \title{Summarize a numeric vector} 6 | \usage{ 7 | cross_summary(x, dig = 1, ...) 8 | } 9 | \arguments{ 10 | \item{x}{a numeric vector} 11 | 12 | \item{dig}{number of digits} 13 | 14 | \item{...}{params to pass on to \code{\link[=format_fixed]{format_fixed()}}: \code{zero_digits} and \code{only_round}} 15 | } 16 | \value{ 17 | a list of named functions 18 | } 19 | \description{ 20 | Summarize a numeric vector with min, max, mean, sd, median, IQR, n and missings. 21 | } 22 | \examples{ 23 | cross_summary(iris$Sepal.Length) 24 | cross_summary(iris$Petal.Width, dig=3) 25 | cross_summary(mtcars2$hp_date) 26 | cross_summary(mtcars2$qsec_posix, date_format="\%d/\%m \%H:\%M") 27 | } 28 | \author{ 29 | Dan Chaltiel, David Hajage 30 | } 31 | -------------------------------------------------------------------------------- /man/crosstable-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/crosstable-package.R 3 | \docType{package} 4 | \name{crosstable-package} 5 | \alias{crosstable-package} 6 | \title{crosstable: Crosstables for Descriptive Analyses} 7 | \description{ 8 | \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} 9 | 10 | Create descriptive tables for continuous and categorical variables. Apply summary statistics and counting function, with or without a grouping variable, and create beautiful reports using 'rmarkdown' or 'officer'. You can also compute effect sizes and statistical tests if needed. 11 | } 12 | \details{ 13 | The \code{crosstable}package is centered on the \code{\link[=crosstable]{crosstable()}}` function. 14 | See vignettes for more information. 15 | } 16 | \seealso{ 17 | Useful links: 18 | \itemize{ 19 | \item \url{https://danchaltiel.github.io/crosstable/} 20 | \item \url{https://github.com/DanChaltiel/crosstable/} 21 | \item Report bugs at \url{https://github.com/DanChaltiel/crosstable/issues/} 22 | } 23 | 24 | } 25 | \author{ 26 | \strong{Maintainer}: Dan Chaltiel \email{dan.chaltiel@gmail.com} (\href{https://orcid.org/0000-0003-3488-779X}{ORCID}) 27 | 28 | Other contributors: 29 | \itemize{ 30 | \item David Hajage [conceptor] 31 | } 32 | 33 | } 34 | \keyword{internal} 35 | -------------------------------------------------------------------------------- /man/crosstable_effect_args.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/effect.R 3 | \name{crosstable_effect_args} 4 | \alias{crosstable_effect_args} 5 | \title{Default arguments for calculating and displaying effects in \code{\link[=crosstable]{crosstable()}}} 6 | \usage{ 7 | crosstable_effect_args( 8 | effect_summarize = diff_mean_auto, 9 | effect_tabular = effect_odds_ratio, 10 | effect_survival = effect_survival_coxph, 11 | effect_display = display_effect, 12 | conf_level = 0.95, 13 | digits = 2 14 | ) 15 | } 16 | \arguments{ 17 | \item{effect_summarize}{a function of three arguments (continuous variable, grouping variable and conf_level), used to compare continuous variable. Returns a list of five components: \code{effect} (the effect value(s)), \code{ci} (the matrix of confidence interval(s)), \code{effect.name} (the interpretation(s) of the effect value(s)), \code{effect.type} (the description of the measure used) and \code{conf_level} (the confidence interval level). Users can use \code{\link[=diff_mean_auto]{diff_mean_auto()}}, \code{\link[=diff_mean_student]{diff_mean_student()}}, \code{\link[=diff_mean_boot]{diff_mean_boot()}}, or \code{\link[=diff_median]{diff_median()}}, or their custom own function.} 18 | 19 | \item{effect_tabular}{a function of three arguments (two categorical variables and conf_level) used to measure the associations between two factors. Returns a list of five components: \code{effect} (the effect value(s)), \code{ci} (the matrix of confidence interval(s)), \code{effect.name} (the interpretation(s) of the effect value(s)), \code{effect.type} (the description of the measure used) and \code{conf_level} (the confidence interval level).Users can use \code{\link[=effect_odds_ratio]{effect_odds_ratio()}}, \code{\link[=effect_relative_risk]{effect_relative_risk()}}, or \code{\link[=effect_risk_difference]{effect_risk_difference()}}, or their custom own function.} 20 | 21 | \item{effect_survival}{a function of two argument (a formula and conf_level), used to measure the association between a censored and a factor. Returns the same components as created by \code{effect_summarize}.Users can use \code{\link[=effect_survival_coxph]{effect_survival_coxph()}} or their custom own function.} 22 | 23 | \item{effect_display}{a function to format the effect. See \code{\link[=display_effect]{display_effect()}}.} 24 | 25 | \item{conf_level}{the desired confidence interval level} 26 | 27 | \item{digits}{the decimal places} 28 | } 29 | \value{ 30 | A list with effect parameters 31 | } 32 | \description{ 33 | This helper function provides default parameters for defining how the effect sizes should be computed. It belongs to the \code{effect_args} argument of the \code{\link[=crosstable]{crosstable()}} function. See \link{effect_summary}, \link{effect_tabular}, and \link{effect_survival} for more insight. 34 | } 35 | \author{ 36 | Dan Chaltiel 37 | } 38 | -------------------------------------------------------------------------------- /man/crosstable_peek_options.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/options.R 3 | \name{crosstable_peek_options} 4 | \alias{crosstable_peek_options} 5 | \title{See which \code{crosstable} option is currently set.} 6 | \usage{ 7 | crosstable_peek_options(keep_null = FALSE) 8 | } 9 | \arguments{ 10 | \item{keep_null}{set to TRUE to get a list} 11 | } 12 | \value{ 13 | A named list of crosstable options 14 | } 15 | \description{ 16 | See which \code{crosstable} option is currently set. 17 | } 18 | -------------------------------------------------------------------------------- /man/crosstable_reset_options.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/options.R 3 | \name{crosstable_reset_options} 4 | \alias{crosstable_reset_options} 5 | \title{Reset all \code{crosstable} options.} 6 | \usage{ 7 | crosstable_reset_options(quiet = FALSE) 8 | } 9 | \arguments{ 10 | \item{quiet}{set to \code{TRUE} to remove the message.} 11 | } 12 | \value{ 13 | Nothing, called for its side effects 14 | } 15 | \description{ 16 | Reset all \code{crosstable} options. 17 | } 18 | -------------------------------------------------------------------------------- /man/crosstable_test_args.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test.R 3 | \name{crosstable_test_args} 4 | \alias{crosstable_test_args} 5 | \alias{test_args} 6 | \title{Default arguments for calculating and displaying tests in \code{\link[=crosstable]{crosstable()}}} 7 | \usage{ 8 | crosstable_test_args( 9 | test_summarize = test_summarize_auto, 10 | test_tabular = test_tabular_auto, 11 | test_correlation = test_correlation_auto, 12 | test_survival = test_survival_logrank, 13 | test_display = display_test, 14 | plim = 4, 15 | show_method = TRUE 16 | ) 17 | } 18 | \arguments{ 19 | \item{test_summarize}{a function of two arguments (continuous variable and grouping variable), used to compare continuous variable. Must return a list of two components: \code{p.value} and \code{method}. See \code{\link{test_summarize_auto}} or \code{\link{test_summarize_linear_contrasts}} for some examples of such functions.} 20 | 21 | \item{test_tabular}{a function of two arguments (two categorical variables), used to test association between two categorical variables. Must return a list of two components: \code{p.value} and \code{method}. See \code{\link{test_tabular_auto}} for example.} 22 | 23 | \item{test_correlation}{a function of three arguments (two continuous variables plus the correlation method), used to test association between two continuous variables. Like \code{cor.test}, it must return a list of at least \code{estimate}, \code{p.value}, and \code{method}, with also \code{conf.int} optionally. See \code{\link{test_correlation_auto}} for example.} 24 | 25 | \item{test_survival}{a function of one argument (the formula \code{surv~by}), used to compare survival estimations. Must return a list of two components: \code{p.value} and \code{method}. See \code{\link{test_survival_logrank}} for example.} 26 | 27 | \item{test_display}{function used to display the test result. See \code{\link{display_test}}.} 28 | 29 | \item{plim}{number of digits for the p value.} 30 | 31 | \item{show_method}{whether to display the test name (logical).} 32 | } 33 | \value{ 34 | A list with test parameters 35 | } 36 | \description{ 37 | This is the starting point for refining the testing algorithm used in crosstable. Users can provide their own functions for test.~. 38 | } 39 | \examples{ 40 | library(dplyr) 41 | my_test_args=crosstable_test_args() 42 | my_test_args$test_summarize = test_summarize_linear_contrasts 43 | iris \%>\% 44 | mutate(Petal.Width.qt = paste0("Q", ntile(Petal.Width, 5)) \%>\% ordered()) \%>\% 45 | crosstable(Petal.Length ~ Petal.Width.qt, test=TRUE, test_args = my_test_args) 46 | } 47 | \seealso{ 48 | \code{\link{test_summarize_auto}}, \code{\link{test_tabular_auto}}, \code{\link{test_survival_logrank}}, \code{\link{test_summarize_linear_contrasts}}, \code{\link{display_test}} 49 | } 50 | \author{ 51 | Dan Chaltiel 52 | } 53 | -------------------------------------------------------------------------------- /man/ct_compact.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compact.R 3 | \name{ct_compact} 4 | \alias{ct_compact} 5 | \alias{ct_compact.data.frame} 6 | \alias{ct_compact.crosstable} 7 | \alias{ct_compact.default} 8 | \alias{compact} 9 | \alias{compact.data.frame} 10 | \alias{compact.crosstable} 11 | \alias{compact.default} 12 | \title{Generic function to compact a table (publication formatting)} 13 | \usage{ 14 | \method{ct_compact}{data.frame}( 15 | data, 16 | name_from, 17 | name_to = "variable", 18 | ..., 19 | id_from = name_from, 20 | wrap_cols = NULL, 21 | rtn_flextable = FALSE 22 | ) 23 | 24 | \method{ct_compact}{crosstable}( 25 | data, 26 | name_from = c("label", ".id"), 27 | name_to = "variable", 28 | id_from = ".id", 29 | keep_id = FALSE, 30 | ... 31 | ) 32 | } 33 | \arguments{ 34 | \item{data}{the object to compact} 35 | 36 | \item{...}{additional arguments (not used)} 37 | 38 | \item{name_from}{name of the column to be collapsed when compacting} 39 | 40 | \item{name_to}{name of the column that will receive the collapsed column. Will be created if it doesn't exist.} 41 | 42 | \item{id_from}{name of the columns to use as cut-off. Useful when successive \code{name_from} have the same value.} 43 | 44 | \item{wrap_cols}{name of the columns to wrap} 45 | 46 | \item{rtn_flextable}{whether to return a formatted \code{\link[flextable:flextable]{flextable::flextable()}} object or a simple \code{data.frame}} 47 | 48 | \item{keep_id}{\code{glue} pattern to keep the column name along with the label. If \code{TRUE}, default to \code{"{label} ({.id})"}.} 49 | } 50 | \value{ 51 | a compacted data.frame 52 | } 53 | \description{ 54 | Generic function to compact a table (publication formatting) 55 | } 56 | \examples{ 57 | #dataframes 58 | x=iris[c(1:5,51:55,101:105),] 59 | ct_compact(x, name_from="Species") 60 | ct_compact(x, name_from="Species", name_to="Petal.Length") 61 | x$Species2 = substr(x$Species, 1, 1) 62 | ct_compact(x, name_from="Species", wrap_cols="Species2") 63 | ct_compact(x, name_from="Species", id_from="Species2") #cut on "v" 64 | 65 | #crosstables 66 | x=crosstable(mtcars2, c(disp,hp,am), by=vs, test=TRUE, effect=TRUE) 67 | ct_compact(x) 68 | ct_compact(x, name_from=".id") 69 | } 70 | \author{ 71 | Dan Chaltiel 72 | } 73 | -------------------------------------------------------------------------------- /man/display_effect.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/effect.R 3 | \name{display_effect} 4 | \alias{display_effect} 5 | \title{Default function to display the effect} 6 | \usage{ 7 | display_effect(effect, digits = 4) 8 | } 9 | \arguments{ 10 | \item{effect}{effect} 11 | 12 | \item{digits}{digits} 13 | } 14 | \value{ 15 | a character vector 16 | } 17 | \description{ 18 | User can provide their own custom version in \code{\link[=crosstable_effect_args]{crosstable_effect_args()}} 19 | } 20 | \author{ 21 | Dan Chaltiel 22 | } 23 | -------------------------------------------------------------------------------- /man/display_test.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test.R 3 | \name{display_test} 4 | \alias{display_test} 5 | \title{Default function to display a test result} 6 | \usage{ 7 | display_test(test, digits = 4, method = TRUE) 8 | } 9 | \arguments{ 10 | \item{test}{test} 11 | 12 | \item{digits}{number of digits} 13 | 14 | \item{method}{display method} 15 | } 16 | \value{ 17 | a string 18 | } 19 | \description{ 20 | Default function to display a test result 21 | } 22 | \author{ 23 | Dan Chaltiel 24 | } 25 | -------------------------------------------------------------------------------- /man/docx_bookmarks2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{docx_bookmarks2} 4 | \alias{docx_bookmarks2} 5 | \title{List Word bookmarks, including the ones in header and footer} 6 | \usage{ 7 | docx_bookmarks2( 8 | x, 9 | return_vector = FALSE, 10 | target = c("all", "header", "body", "footer") 11 | ) 12 | } 13 | \arguments{ 14 | \item{x}{an \code{rdocx} object} 15 | 16 | \item{return_vector}{use \code{TRUE} for compatibility with \code{\link[officer:docx_bookmarks]{officer::docx_bookmarks()}}} 17 | 18 | \item{target}{one of c("all", "header", "body", "footer")} 19 | } 20 | \value{ 21 | a list with all bookmarks 22 | } 23 | \description{ 24 | This is a correction of \code{\link[officer:docx_bookmarks]{officer::docx_bookmarks()}}. See \href{https://github.com/davidgohel/officer/pull/313}{this PR}. 25 | } 26 | \author{ 27 | Dan Chaltiel 28 | } 29 | -------------------------------------------------------------------------------- /man/effect_summary.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/effect.R 3 | \name{effect_summary} 4 | \alias{effect_summary} 5 | \alias{diff_mean_auto} 6 | \alias{diff_mean_boot} 7 | \alias{diff_median_boot} 8 | \alias{diff_median} 9 | \alias{diff_mean_student} 10 | \title{Effect measure for association between one continuous and one categorical variable} 11 | \usage{ 12 | diff_mean_auto(x, by, conf_level = 0.95, R = 500) 13 | 14 | diff_mean_boot(x, by, conf_level = 0.95, R = 500) 15 | 16 | diff_median_boot(x, by, conf_level = 0.95, R = 500) 17 | 18 | diff_mean_student(x, by, conf_level = 0.95) 19 | } 20 | \arguments{ 21 | \item{x}{numeric vector} 22 | 23 | \item{by}{categorical vector (of exactly 2 unique levels)} 24 | 25 | \item{conf_level}{confidence interval level} 26 | 27 | \item{R}{number of bootstrap replication} 28 | } 29 | \value{ 30 | A list with five components: effect, ci, effect.name, effect.type, and conf_level 31 | } 32 | \description{ 33 | User can either use or extend these functions to configure effect calculation. 34 | } 35 | \section{Functions}{ 36 | \itemize{ 37 | \item \code{diff_mean_auto()}: (\strong{Default}) calculate a specific "difference in means" effect based on normality (Shapiro or Anderson test) and variance homogeneity (Bartlett test) 38 | 39 | \item \code{diff_mean_boot()}: calculate a "difference in means" effect with a bootstrapped CI using standard deviation 40 | 41 | \item \code{diff_median_boot()}: calculate a "difference in medians" effect with a bootstrapped CI using quantiles#' 42 | 43 | \item \code{diff_mean_student()}: calculate a "difference in means" effect using \code{t.test} confidence intervals 44 | 45 | }} 46 | \seealso{ 47 | \code{\link[=crosstable_effect_args]{crosstable_effect_args()}} 48 | } 49 | \author{ 50 | Dan Chaltiel, David Hajage 51 | } 52 | -------------------------------------------------------------------------------- /man/effect_survival.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/effect.R 3 | \name{effect_survival} 4 | \alias{effect_survival} 5 | \alias{effect_survival_coxph} 6 | \title{Effect measure for association between one censored variable and one categorical variable} 7 | \usage{ 8 | effect_survival_coxph(x, by, conf_level = 0.95) 9 | } 10 | \arguments{ 11 | \item{x}{survival vector (made using \code{\link[survival:Surv]{survival::Surv()}})} 12 | 13 | \item{by}{categorical vector (of exactly 2 unique levels)} 14 | 15 | \item{conf_level}{confidence interval level} 16 | } 17 | \value{ 18 | a list with two components: p.value and method 19 | } 20 | \description{ 21 | Effect measure for association between one censored variable and one categorical variable 22 | } 23 | \author{ 24 | Dan Chaltiel, David Hajage 25 | } 26 | -------------------------------------------------------------------------------- /man/effect_tabular.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/effect.R 3 | \name{effect_tabular} 4 | \alias{effect_tabular} 5 | \alias{effect_odds_ratio} 6 | \alias{effect_relative_risk} 7 | \alias{effect_risk_difference} 8 | \title{Effect measure for association between two categorical variables} 9 | \usage{ 10 | effect_odds_ratio(x, by, conf_level = 0.95) 11 | 12 | effect_relative_risk(x, by, conf_level = 0.95) 13 | 14 | effect_risk_difference(x, by, conf_level = 0.95) 15 | } 16 | \arguments{ 17 | \item{x}{categorical vector (character, factor, ...)} 18 | 19 | \item{by}{categorical vector (of exactly 2 unique levels)} 20 | 21 | \item{conf_level}{confidence interval level} 22 | } 23 | \value{ 24 | A list with five components: effect, ci, effect.name, effect.type, and conf_level 25 | } 26 | \description{ 27 | User can either use or extend these functions to configure effect calculation. 28 | } 29 | \section{Functions}{ 30 | \itemize{ 31 | \item \code{effect_odds_ratio()}: (\strong{Default}) calculate the odds ratio 32 | 33 | \item \code{effect_relative_risk()}: calculate the relative risk 34 | 35 | \item \code{effect_risk_difference()}: calculate the risk difference 36 | 37 | }} 38 | \seealso{ 39 | \code{\link[=crosstable_effect_args]{crosstable_effect_args()}} 40 | } 41 | \author{ 42 | Dan Chaltiel, David Hajage 43 | } 44 | -------------------------------------------------------------------------------- /man/figures/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /man/figures/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /man/figures/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /man/figures/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /man/figures/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /man/figures/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/apple-touch-icon.png -------------------------------------------------------------------------------- /man/figures/ct.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/ct.pptx -------------------------------------------------------------------------------- /man/figures/ct1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/ct1.png -------------------------------------------------------------------------------- /man/figures/ct1_mod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/ct1_mod.png -------------------------------------------------------------------------------- /man/figures/ct1_mod_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/ct1_mod_twitter.png -------------------------------------------------------------------------------- /man/figures/ct2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/ct2.png -------------------------------------------------------------------------------- /man/figures/ct2_mod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/ct2_mod.png -------------------------------------------------------------------------------- /man/figures/ct2_mod_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/ct2_mod_twitter.png -------------------------------------------------------------------------------- /man/figures/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/favicon-16x16.png -------------------------------------------------------------------------------- /man/figures/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/favicon-32x32.png -------------------------------------------------------------------------------- /man/figures/github-open-graph-crosstable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/github-open-graph-crosstable.png -------------------------------------------------------------------------------- /man/figures/lifecycle-archived.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclearchivedarchived -------------------------------------------------------------------------------- /man/figures/lifecycle-defunct.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycledefunctdefunct -------------------------------------------------------------------------------- /man/figures/lifecycle-deprecated.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycledeprecateddeprecated -------------------------------------------------------------------------------- /man/figures/lifecycle-experimental.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycleexperimentalexperimental -------------------------------------------------------------------------------- /man/figures/lifecycle-maturing.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclematuringmaturing -------------------------------------------------------------------------------- /man/figures/lifecycle-questioning.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclequestioningquestioning -------------------------------------------------------------------------------- /man/figures/lifecycle-soft-deprecated.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclesoft-deprecatedsoft-deprecated -------------------------------------------------------------------------------- /man/figures/lifecycle-stable.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclestablestable -------------------------------------------------------------------------------- /man/figures/lifecycle-superseded.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclesupersededsuperseded -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/logo.png -------------------------------------------------------------------------------- /man/figures/officer-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/officer-example.png -------------------------------------------------------------------------------- /man/figures/tests.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/tests.pptx -------------------------------------------------------------------------------- /man/figures/vignette_officer.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/man/figures/vignette_officer.docx -------------------------------------------------------------------------------- /man/format_fixed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/funs.R 3 | \name{format_fixed} 4 | \alias{format_fixed} 5 | \title{Format numbers with the exact same number of decimals, including trailing zeros} 6 | \usage{ 7 | format_fixed( 8 | x, 9 | digits = 1, 10 | zero_digits = 1, 11 | date_format = NULL, 12 | percent = FALSE, 13 | is_period = FALSE, 14 | scientific = getOption("crosstable_scientific_log", 4), 15 | epsilon = getOption("crosstable_format_epsilon", NULL), 16 | only_round = getOption("crosstable_only_round", FALSE), 17 | ... 18 | ) 19 | } 20 | \arguments{ 21 | \item{x}{a numeric vector to format} 22 | 23 | \item{digits}{number of decimals} 24 | 25 | \item{zero_digits}{number of significant digits for values rounded to 0 (can be set to NULL to keep the original 0 value)} 26 | 27 | \item{date_format}{if \code{x} is a vector of Date or POSIXt, the format to apply (see \link{strptime} for formats)} 28 | 29 | \item{percent}{if TRUE, format the values as percentages} 30 | 31 | \item{is_period}{whether \code{x} is a period (a numeric value of seconds)} 32 | 33 | \item{scientific}{the power of ten above/under which numbers will be displayed as scientific notation.} 34 | 35 | \item{epsilon}{values less than \code{epsilon} are formatted as \code{"< [epsilon]"}} 36 | 37 | \item{only_round}{if TRUE, \code{format_fixed} simply returns the rounded value. Can be set globally with \code{options("crosstable_only_round"=TRUE)}.} 38 | 39 | \item{...}{unused} 40 | } 41 | \value{ 42 | a character vector of formatted numbers 43 | } 44 | \description{ 45 | Format numbers with the exact same number of decimals, including trailing zeros 46 | } 47 | \examples{ 48 | x = c(1, 1.2, 12.78749, pi, 0.00000012) 49 | format_fixed(x, digits=3) #default zero_digits=1 50 | format_fixed(x, digits=3, zero_digits=2) 51 | format_fixed(x, digits=3, zero_digits=NULL) 52 | 53 | x_sd = sd(iris$Sepal.Length/10000, na.rm=TRUE) 54 | format_fixed(x_sd, dig=6) 55 | format_fixed(x_sd, dig=3, zero_digits=2) #default only_round=FALSE 56 | format_fixed(x_sd, dig=3, zero_digits=2, only_round=TRUE) 57 | options("crosstable_only_round"=TRUE) 58 | format_fixed(x_sd, dig=3, zero_digits=2) #override default 59 | options("crosstable_only_round"=NULL) 60 | 61 | x2 = c(0.01, 0.1001, 0.500005, 0.00000012) 62 | format_fixed(x2, scientific=0, dig=1) #everything abs>10^0 gets scientific 63 | #last would be 0 so it is scientific. Try `zero_digits=NA` or `dig=7` 64 | format_fixed(x2, scientific=FALSE, dig=6) 65 | format_fixed(x2, scientific=FALSE, percent=TRUE, dig=0) 66 | format_fixed(x2, scientific=FALSE, eps=0.05) 67 | } 68 | \author{ 69 | Dan Chaltiel 70 | } 71 | -------------------------------------------------------------------------------- /man/generate_autofit_macro.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{generate_autofit_macro} 4 | \alias{generate_autofit_macro} 5 | \title{Generate a macro file for autofitting} 6 | \usage{ 7 | generate_autofit_macro() 8 | } 9 | \value{ 10 | Nothing, called for its side effects 11 | } 12 | \description{ 13 | Autofitting using existing tools in flextable should be enough for most cases. For the others, here is a VBA macro which autofits all tables from inside MS Word. 14 | This function generates a file that can be imported into MS Word in order to use this macro. The macro file should be imported only once per computer. 15 | } 16 | \section{Installation}{ 17 | 18 | \itemize{ 19 | \item In the \code{R} console, run \code{generate_autofit_macro()} to generate the file \code{crosstable_autofit.bas} in your working directory. 20 | \item In MS Word, press Alt+F11 to open the VB Editor. 21 | \item In the Editor, go to \code{File} > \code{Import} or press \code{Ctrl+M} to open the import dialog, and import \code{crosstable_autofit.bas}. There should now be a "CrosstableMacros" module in the "Normal" project. 22 | \item Run the macro, either from the VB Editor or from \code{View} > \code{Macros} > \verb{View Macros} > \code{Run}. 23 | } 24 | 25 | This process will make the macro accessible from any Word file on this computer. Note that, in the Editor, you can also drag the module to your document project to make the macro accessible only from this file. The file will have to be named with the \code{docm} extension though. 26 | } 27 | 28 | \author{ 29 | Dan Chaltiel 30 | } 31 | -------------------------------------------------------------------------------- /man/get_label.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.R 3 | \name{get_label} 4 | \alias{get_label} 5 | \title{Get label if wanted and available, or default (name) otherwise} 6 | \usage{ 7 | get_label(x, default = names(x), object = FALSE, simplify = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{labelled object. If \code{x} is a list/data.frame, \code{get_label()} will return the labels of all children recursively} 11 | 12 | \item{default}{value returned if there is no label. Default to \code{names(x)}.} 13 | 14 | \item{object}{if \code{x} is a list/data.frame, \code{object=TRUE} will force getting the labels of the object instead of the children} 15 | 16 | \item{simplify}{if \code{x} is a list and \code{object=FALSE}, simplify the result to a vector} 17 | } 18 | \value{ 19 | A character vector if \code{simplify==TRUE}, a list otherwise 20 | } 21 | \description{ 22 | Get label if wanted and available, or default (name) otherwise 23 | } 24 | \examples{ 25 | xx=mtcars2 \%>\% 26 | set_label("The mtcars2 dataset", object=TRUE) 27 | xx$cyl=remove_label(xx$cyl) 28 | 29 | #vectors 30 | get_label(xx$mpg) #label="Miles/(US) gallon" 31 | get_label(xx$cyl) #default to NULL (since names(xx$cyl)==NULL) 32 | get_label(xx$cyl, default="Default value") 33 | 34 | #data.frames 35 | get_label(xx) 36 | get_label(xx, object=TRUE) 37 | data.frame(name=names(xx), label=get_label(xx, default=NA)) #cyl is NA 38 | 39 | #lists 40 | get_label(list(xx$cyl, xx$mpg)) #cyl is NA 41 | get_label(list(foo=xx$cyl, bar=xx$mpg)) #default to names 42 | get_label(list(foo=xx$cyl, bar=xx$mpg), default="Default value") 43 | } 44 | \seealso{ 45 | \code{\link[=set_label]{set_label()}}, \code{\link[=import_labels]{import_labels()}}, \code{\link[=remove_label]{remove_label()}}, \code{\link[Hmisc:label]{Hmisc::label()}}, \code{\link[expss:var_lab]{expss::var_lab()}} 46 | } 47 | \author{ 48 | Dan Chaltiel 49 | } 50 | -------------------------------------------------------------------------------- /man/get_percent_pattern.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cross_categorical.R 3 | \name{get_percent_pattern} 4 | \alias{get_percent_pattern} 5 | \title{Percent pattern helper} 6 | \usage{ 7 | get_percent_pattern( 8 | margin = c("row", "column", "cell", "none", "all"), 9 | na = FALSE, 10 | warn_duplicates = TRUE 11 | ) 12 | } 13 | \arguments{ 14 | \item{margin}{a vector giving the margins to compute.} 15 | 16 | \item{na}{whether to use \code{NA}} 17 | 18 | \item{warn_duplicates}{whether to warn if margin has duplicates} 19 | } 20 | \value{ 21 | a list 22 | } 23 | \description{ 24 | Get a list with pre-filled values for \code{percent_pattern}. 25 | } 26 | \examples{ 27 | get_percent_pattern(c("cells","row","column")) 28 | get_percent_pattern(c("cells","row","column"), na=TRUE) 29 | } 30 | -------------------------------------------------------------------------------- /man/import_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.R 3 | \name{import_labels} 4 | \alias{import_labels} 5 | \alias{save_labels} 6 | \title{Import labels} 7 | \usage{ 8 | import_labels( 9 | .tbl, 10 | data_label, 11 | name_from = "name", 12 | label_from = "label", 13 | warn_name = FALSE, 14 | warn_label = FALSE, 15 | verbose = deprecated() 16 | ) 17 | 18 | save_labels(.tbl) 19 | } 20 | \arguments{ 21 | \item{.tbl}{the data.frame to be labelled} 22 | 23 | \item{data_label}{a data.frame from which to import labels. If missing, the function will take the labels from the last dataframe on which \code{\link[=save_labels]{save_labels()}} was called.} 24 | 25 | \item{name_from}{in \code{data_label}, which column to get the variable name (default to \code{name})} 26 | 27 | \item{label_from}{in \code{data_label}, which column to get the variable label (default to \code{label})} 28 | 29 | \item{warn_name}{if TRUE, displays a warning if a variable name is not found in \code{data_label}} 30 | 31 | \item{warn_label}{if TRUE, displays a warning if a label is not found in \code{.tbl}} 32 | 33 | \item{verbose}{deprecated} 34 | } 35 | \value{ 36 | A dataframe, as \code{.tbl}, with labels 37 | 38 | \code{.tbl} invisibly. Used only for its side effects. 39 | } 40 | \description{ 41 | \code{import_labels} imports labels from a data.frame (\code{data_label}) to another one (\code{.tbl}). Works in synergy with \code{\link[=save_labels]{save_labels()}}. 42 | 43 | \code{save_labels} saves the labels from a data.frame in a temporary variable that can be retrieve by \code{import_labels}. 44 | } 45 | \examples{ 46 | #import the labels from a data.frame to another 47 | iris_label = data.frame( 48 | name=c("Sepal.Length", "Sepal.Width", 49 | "Petal.Length", "Petal.Width", "Species"), 50 | label=c("Length of Sepals", "Width of Sepals", 51 | "Length of Petals", "Width of Petals", "Specie name") 52 | ) 53 | iris \%>\% 54 | import_labels(iris_label) \%>\% 55 | crosstable 56 | 57 | #save the labels, use some dplyr label-removing function, then retrieve the labels 58 | library(dplyr) 59 | mtcars2 \%>\% 60 | save_labels() \%>\% 61 | transmute(disp=as.numeric(disp)+1) \%>\% 62 | import_labels(warn_label=FALSE) \%>\% # 63 | crosstable(disp) 64 | } 65 | \seealso{ 66 | \code{\link[=get_label]{get_label()}}, \code{\link[=set_label]{set_label()}}, \code{\link[=remove_label]{remove_label()}}, \code{\link[=save_labels]{save_labels()}} 67 | } 68 | \author{ 69 | Dan Chaltiel 70 | } 71 | -------------------------------------------------------------------------------- /man/iris2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dataset.R 3 | \docType{data} 4 | \name{iris2} 5 | \alias{iris2} 6 | \title{Modified \code{iris} dataset} 7 | \format{ 8 | A data frame with 150 observations on 5 variables with labels. 9 | } 10 | \source{ 11 | \preformatted{ 12 | library(dplyr) 13 | iris2 = iris \%>\% 14 | expss::apply_labels( #I also could have used [import_labels] or even `labelled::set_variable_labels()` 15 | Species = "Specie", 16 | Sepal.Length = "Length of Sepal", 17 | Sepal.Width = "Width of Sepal", 18 | Petal.Length = "Length of Petal", 19 | Petal.Width = "Width of Petal" 20 | ) \%>\% 21 | as_tibble() 22 | } 23 | } 24 | \usage{ 25 | iris2 26 | } 27 | \description{ 28 | Modified \code{iris} dataset so: 29 | \itemize{ 30 | \item every column is labelled (using \code{label} attribute) 31 | \item \code{Species} column is considered as factor 32 | } 33 | 34 | See \code{\link{iris}} for more informations on the original "Edgar Anderson's Iris Data" dataset. 35 | } 36 | \examples{ 37 | library(crosstable) 38 | ct=crosstable(iris2, by=Species) 39 | ct 40 | as_flextable(ct) 41 | } 42 | \keyword{datasets} 43 | -------------------------------------------------------------------------------- /man/is.crosstable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{is.crosstable} 4 | \alias{is.crosstable} 5 | \alias{is.transposed_crosstable} 6 | \alias{is.compacted_crosstable} 7 | \alias{is.multiby_crosstable} 8 | \title{Test if an object is a crosstable} 9 | \usage{ 10 | is.crosstable(x) 11 | 12 | is.transposed_crosstable(x) 13 | 14 | is.compacted_crosstable(x) 15 | 16 | is.multiby_crosstable(x) 17 | } 18 | \arguments{ 19 | \item{x}{An object} 20 | } 21 | \value{ 22 | TRUE if the object inherits from the \code{crosstable} class or other subclasses. 23 | } 24 | \description{ 25 | Test if an object is a crosstable 26 | } 27 | -------------------------------------------------------------------------------- /man/mtcars2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/dataset.R 3 | \docType{data} 4 | \name{mtcars2} 5 | \alias{mtcars2} 6 | \title{Modified \code{mtcars} dataset} 7 | \format{ 8 | A data frame with 32 observations on 11 variables with labels. 9 | } 10 | \source{ 11 | \preformatted{ 12 | library(dplyr) 13 | mtcars2 = mtcars \%>\% 14 | mutate( 15 | model=rownames(mtcars), 16 | vs=ifelse(vs==0, "vshaped", "straight"), 17 | am=ifelse(am==0, "auto", "manual"), 18 | across(c("cyl", "gear"), factor), 19 | .before=1 20 | ) \%>\% 21 | expss::apply_labels( #I also could have used [import_labels] or even `labelled::set_variable_labels()` 22 | mpg="Miles/(US) gallon", 23 | cyl="Number of cylinders", 24 | disp="Displacement (cu.in.)", 25 | hp="Gross horsepower", 26 | drat="Rear axle ratio", 27 | wt="Weight (1000 lbs)", 28 | qsec="1/4 mile time", 29 | vs="Engine", 30 | am="Transmission", 31 | gear="Number of forward gears", 32 | carb="Number of carburetors" 33 | ) 34 | } 35 | } 36 | \usage{ 37 | mtcars2 38 | } 39 | \description{ 40 | Modified \code{mtcars} dataset so: 41 | \itemize{ 42 | \item every column is labelled (using \code{label} attribute) 43 | \item rownames are a character column named \code{model} 44 | \item \code{gear} and \code{cyl} columns are considered as numerical factors 45 | \item \code{vs} and \code{am} columns are considered as character vector 46 | } 47 | 48 | See \code{\link{mtcars}} for more informations on the original "Motor Trend Car Road Tests" dataset. 49 | } 50 | \examples{ 51 | library(crosstable) 52 | ct=crosstable(mtcars2, by=vs) 53 | ct 54 | as_flextable(ct) 55 | } 56 | \keyword{datasets} 57 | -------------------------------------------------------------------------------- /man/n.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/funs.R 3 | \name{N} 4 | \alias{N} 5 | \title{Return the number of non NA observations} 6 | \usage{ 7 | N(x) 8 | } 9 | \arguments{ 10 | \item{x}{a vector} 11 | } 12 | \value{ 13 | integer, number of non NA observations 14 | } 15 | \description{ 16 | Return the number of non NA observations 17 | } 18 | \author{ 19 | David Hajage 20 | } 21 | -------------------------------------------------------------------------------- /man/na.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/funs.R 3 | \name{na} 4 | \alias{na} 5 | \title{Return the number of NA observations} 6 | \usage{ 7 | na(x) 8 | } 9 | \arguments{ 10 | \item{x}{a vector} 11 | } 12 | \value{ 13 | integer, number of NA observations 14 | } 15 | \description{ 16 | Return the number of NA observations 17 | } 18 | \author{ 19 | David Hajage 20 | } 21 | -------------------------------------------------------------------------------- /man/narm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/funs.R 3 | \name{narm} 4 | \alias{narm} 5 | \title{Remove missing values} 6 | \usage{ 7 | narm(x) 8 | } 9 | \arguments{ 10 | \item{x}{a vector} 11 | } 12 | \value{ 13 | the same vector without missing values 14 | } 15 | \description{ 16 | Remove missing values 17 | } 18 | -------------------------------------------------------------------------------- /man/peek.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/flextable.R 3 | \name{peek} 4 | \alias{peek} 5 | \title{Open a \code{crosstable} in a temporary document} 6 | \usage{ 7 | peek(x, docx = getOption("crosstable_peek_docx", TRUE), ...) 8 | } 9 | \arguments{ 10 | \item{x}{a crosstable} 11 | 12 | \item{docx}{if true, peek as a \code{docx}, else, peek as \code{xlsx}} 13 | 14 | \item{...}{passed on to \code{as_flextable.crosstable()} or to \code{as_workbook()}} 15 | } 16 | \value{ 17 | Nothing, called for its side effects 18 | } 19 | \description{ 20 | This eases copy-pasting 21 | } 22 | \author{ 23 | Dan Chaltiel 24 | } 25 | -------------------------------------------------------------------------------- /man/pivot_crosstable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pivot.R 3 | \name{pivot_crosstable} 4 | \alias{pivot_crosstable} 5 | \title{Pivot a crosstable} 6 | \usage{ 7 | pivot_crosstable(ct) 8 | } 9 | \arguments{ 10 | \item{ct}{a crosstable} 11 | } 12 | \value{ 13 | a tibble of class \code{pivoted_crosstable} 14 | } 15 | \description{ 16 | Pivot a crosstable so the \code{variable} column is spread across its values. 17 | } 18 | \examples{ 19 | ct = crosstable(mtcars2, c(mpg, drat, wt, qsec)) 20 | p_ct = pivot_crosstable(ct) 21 | as_flextable(p_ct) 22 | } 23 | -------------------------------------------------------------------------------- /man/plim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/funs.R 3 | \name{plim} 4 | \alias{plim} 5 | \title{Format p values (alternative to \code{\link[=format.pval]{format.pval()}})} 6 | \usage{ 7 | plim(p, digits = 4) 8 | } 9 | \arguments{ 10 | \item{p}{p values} 11 | 12 | \item{digits}{number of digits} 13 | } 14 | \value{ 15 | formatted p values 16 | } 17 | \description{ 18 | Format p values (alternative to \code{\link[=format.pval]{format.pval()}}) 19 | } 20 | \seealso{ 21 | \code{\link[=format.pval]{format.pval()}}, https://stackoverflow.com/a/23018806/3888000 22 | } 23 | \author{ 24 | David Hajage 25 | } 26 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reexport.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{\%>\%} 7 | \alias{everything} 8 | \alias{all_of} 9 | \alias{any_of} 10 | \alias{starts_with} 11 | \alias{ends_with} 12 | \alias{contains} 13 | \alias{matches} 14 | \title{Objects exported from other packages} 15 | \keyword{internal} 16 | \description{ 17 | These objects are imported from other packages. Follow the links 18 | below to see their documentation. 19 | 20 | \describe{ 21 | \item{dplyr}{\code{\link[dplyr:reexports]{\%>\%}}, \code{\link[dplyr:reexports]{all_of}}, \code{\link[dplyr:reexports]{any_of}}, \code{\link[dplyr:reexports]{contains}}, \code{\link[dplyr:reexports]{ends_with}}, \code{\link[dplyr:reexports]{everything}}, \code{\link[dplyr:reexports]{matches}}, \code{\link[dplyr:reexports]{starts_with}}} 22 | }} 23 | 24 | -------------------------------------------------------------------------------- /man/remove_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.R 3 | \name{remove_labels} 4 | \alias{remove_labels} 5 | \alias{remove_label} 6 | \title{Remove all label attributes.} 7 | \usage{ 8 | remove_labels(x) 9 | } 10 | \arguments{ 11 | \item{x}{object to unlabel} 12 | } 13 | \value{ 14 | An object of the same type as \code{x}, with no labels 15 | } 16 | \description{ 17 | Use \code{remove_labels()} to remove the label from an object or to recursively remove all the labels from a collection of objects (such as a list or a data.frame). \cr \cr This can be useful with functions reacting badly to labelled objects. 18 | } 19 | \examples{ 20 | mtcars2 \%>\% remove_labels \%>\% crosstable(mpg) #no label 21 | mtcars2$hp \%>\% remove_labels \%>\% get_label() #NULL 22 | } 23 | \seealso{ 24 | \link{get_label}, \link{set_label}, \link{import_labels}, \link[expss:unlab]{expss::unlab} 25 | } 26 | \author{ 27 | Dan Chaltiel 28 | } 29 | -------------------------------------------------------------------------------- /man/rename_with_labels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.R 3 | \name{rename_with_labels} 4 | \alias{rename_with_labels} 5 | \alias{rename_dataframe_with_labels} 6 | \title{Rename every column of a dataframe with its label} 7 | \source{ 8 | https://stackoverflow.com/q/75848408/3888000 9 | } 10 | \usage{ 11 | rename_with_labels(df, except = NULL) 12 | } 13 | \arguments{ 14 | \item{df}{a data.frame} 15 | 16 | \item{except}{<\code{\link[tidyselect:language]{tidy-select}}> columns that should not be renamed.} 17 | } 18 | \value{ 19 | A dataframe which names are copied from the label attribute 20 | } 21 | \description{ 22 | Rename every column of a dataframe with its label 23 | } 24 | \examples{ 25 | rename_with_labels(mtcars2[,1:5], except=5) \%>\% names() 26 | rename_with_labels(iris2, except=Sepal.Length) \%>\% names() 27 | rename_with_labels(iris2, except=starts_with("Pet")) \%>\% names() 28 | } 29 | \author{ 30 | Dan Chaltiel 31 | } 32 | -------------------------------------------------------------------------------- /man/set_label.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/labels.R 3 | \name{set_label} 4 | \alias{set_label} 5 | \alias{copy_label_from} 6 | \title{Set the "label" attribute of an object} 7 | \usage{ 8 | set_label(x, value, object = FALSE) 9 | 10 | copy_label_from(x, from) 11 | } 12 | \arguments{ 13 | \item{x}{the variable to label} 14 | 15 | \item{value}{value of the label. If \code{x} is a list/data.frame, the labels will all be set recursively. If \code{value} is a function, it will be applied to the current labels of \code{x}.} 16 | 17 | \item{object}{if \code{x} is a list/data.frame, \code{object=TRUE} will force setting the labels of the object instead of the children} 18 | 19 | \item{from}{the variable whose label must be copied} 20 | } 21 | \value{ 22 | An object of the same type as \code{x}, with labels 23 | } 24 | \description{ 25 | Set the "label" attribute of an object 26 | 27 | Copy the label from one variable to another 28 | } 29 | \examples{ 30 | library(dplyr) 31 | mtcars \%>\% 32 | mutate(mpg2=set_label(mpg, "Miles per gallon"), 33 | mpg3=mpg \%>\% copy_label_from(mpg2)) \%>\% 34 | crosstable(c(mpg, mpg2, mpg3)) 35 | mtcars \%>\% 36 | copy_label_from(mtcars2) \%>\% 37 | crosstable(c(mpg, vs)) 38 | mtcars2 \%>\% set_label(toupper) \%>\% get_label() 39 | } 40 | \seealso{ 41 | \code{\link[=get_label]{get_label()}}, \code{\link[=import_labels]{import_labels()}}, \code{\link[=remove_label]{remove_label()}} 42 | } 43 | \author{ 44 | Dan Chaltiel 45 | } 46 | -------------------------------------------------------------------------------- /man/summaryFunctions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/funs.R 3 | \name{summaryFunctions} 4 | \alias{summaryFunctions} 5 | \alias{meansd} 6 | \alias{moystd} 7 | \alias{meanCI} 8 | \alias{mediqr} 9 | \alias{minmax} 10 | \alias{nna} 11 | \title{Summary functions} 12 | \usage{ 13 | meansd(x, na.rm = TRUE, dig = 2, ...) 14 | 15 | meanCI(x, na.rm = TRUE, dig = 2, level = 0.95, format = TRUE, ...) 16 | 17 | mediqr(x, na.rm = TRUE, dig = 2, format = TRUE, ...) 18 | 19 | minmax(x, na.rm = TRUE, dig = 2, ...) 20 | 21 | nna(x) 22 | } 23 | \arguments{ 24 | \item{x}{a numeric vector} 25 | 26 | \item{na.rm}{\code{TRUE} as default} 27 | 28 | \item{dig}{number of digits} 29 | 30 | \item{...}{params to pass on to \code{\link[=format_fixed]{format_fixed()}}: 31 | \itemize{ 32 | \item \code{zero_digits} (default=\code{1}): the number of significant digits for values rounded to 0 (set to NULL to keep the original 0 value) 33 | \item \code{only_round} (default=\code{FALSE}): use \code{\link[=round]{round()}} instead of \code{\link[=format_fixed]{format_fixed()}} 34 | }} 35 | 36 | \item{level}{the confidence level required} 37 | 38 | \item{format}{a sugar argument. If FALSE, the function returns a list instead of a formatted string} 39 | } 40 | \value{ 41 | a character vector 42 | } 43 | \description{ 44 | Summary functions to use with \code{\link[=crosstable]{crosstable()}} or anywhere else. 45 | } 46 | \section{Functions}{ 47 | \itemize{ 48 | \item \code{meansd()}: returns mean and std error 49 | 50 | \item \code{meanCI()}: returns mean and confidence interval 51 | 52 | \item \code{mediqr()}: returns median and IQR 53 | 54 | \item \code{minmax()}: returns minimum and maximum 55 | 56 | \item \code{nna()}: returns number of observations and number of missing values 57 | 58 | }} 59 | \section{Fixed format}{ 60 | 61 | These functions use \code{\link[=format_fixed]{format_fixed()}} which allows to have trailing zeros after rounded values. 62 | In the case when the output of rounded values is zero, the use of the \code{zero_digits} argument allows to keep some significant digits for this specific case only. 63 | } 64 | 65 | \examples{ 66 | meansd(iris$Sepal.Length, dig=3) 67 | meanCI(iris$Sepal.Length) 68 | minmax(iris$Sepal.Length, dig=3) 69 | mediqr(iris$Sepal.Length, dig=3) 70 | nna(iris$Sepal.Length) 71 | 72 | #arguments for format_fixed 73 | x = iris$Sepal.Length/10000 #closer to zero 74 | 75 | meansd(x, dig=3) 76 | meansd(x, dig=3, zero_digits=NULL) #or NA 77 | meansd(x, dig=3, only_round=TRUE) 78 | options("crosstable_only_round"=TRUE) 79 | meansd(x, dig=3, zero_digits=2) 80 | options("crosstable_only_round"=NULL) 81 | meanCI(mtcars2$x_date) 82 | 83 | #dates 84 | x = as.POSIXct(mtcars$qsec*3600*24 , origin="2010-01-01") 85 | meansd(x) 86 | minmax(x, date_format="\%d/\%m/\%Y") 87 | 88 | } 89 | \seealso{ 90 | \code{\link[=format_fixed]{format_fixed()}} 91 | } 92 | \author{ 93 | Dan Chaltiel, David Hajage 94 | } 95 | -------------------------------------------------------------------------------- /man/test_correlation_auto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test.R 3 | \name{test_correlation_auto} 4 | \alias{test_correlation_auto} 5 | \title{test for correlation coefficients} 6 | \usage{ 7 | test_correlation_auto(x, by, method) 8 | } 9 | \arguments{ 10 | \item{x}{vector} 11 | 12 | \item{by}{another vector} 13 | 14 | \item{method}{"pearson", "kendall", or "spearman"} 15 | } 16 | \value{ 17 | the correlation test with appropriate method 18 | } 19 | \description{ 20 | test for correlation coefficients 21 | } 22 | \author{ 23 | Dan Chaltiel, David Hajage 24 | } 25 | -------------------------------------------------------------------------------- /man/test_summarize_auto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test.R 3 | \name{test_summarize_auto} 4 | \alias{test_summarize_auto} 5 | \title{test for mean comparison} 6 | \usage{ 7 | test_summarize_auto(x, g) 8 | } 9 | \arguments{ 10 | \item{x}{vector} 11 | 12 | \item{g}{another vector} 13 | } 14 | \value{ 15 | a list with two components: p.value and method 16 | } 17 | \description{ 18 | Compute a oneway.test (with equal or unequal variance) or a 19 | kruskal.test as appropriate. 20 | } 21 | \author{ 22 | Dan Chaltiel, David Hajage 23 | } 24 | -------------------------------------------------------------------------------- /man/test_summarize_linear_contrasts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test.R 3 | \name{test_summarize_linear_contrasts} 4 | \alias{test_summarize_linear_contrasts} 5 | \title{Test for linear trend across ordered factor with contrasts} 6 | \usage{ 7 | test_summarize_linear_contrasts(x, y) 8 | } 9 | \arguments{ 10 | \item{x}{vector} 11 | 12 | \item{y}{ordered factor} 13 | } 14 | \value{ 15 | a list with two components: p.value and method 16 | } 17 | \description{ 18 | Test for linear trend across ordered factor with contrasts 19 | } 20 | \examples{ 21 | library(dplyr) 22 | my_test_args=crosstable_test_args() 23 | my_test_args$test_summarize = test_summarize_linear_contrasts 24 | iris \%>\% 25 | mutate(Petal.Width.qt = paste0("Q", ntile(Petal.Width, 5)) \%>\% ordered()) \%>\% 26 | crosstable(Petal.Length ~ Petal.Width.qt, test=TRUE, test_args = my_test_args) 27 | } 28 | \author{ 29 | Dan Chaltiel 30 | } 31 | -------------------------------------------------------------------------------- /man/test_survival_logrank.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test.R 3 | \name{test_survival_logrank} 4 | \alias{test_survival_logrank} 5 | \title{test for survival comparison} 6 | \usage{ 7 | test_survival_logrank(formula) 8 | } 9 | \arguments{ 10 | \item{formula}{a formula} 11 | } 12 | \value{ 13 | a list with two components: p.value and method 14 | } 15 | \description{ 16 | Compute a logrank test 17 | } 18 | \author{ 19 | Dan Chaltiel, David Hajage 20 | } 21 | -------------------------------------------------------------------------------- /man/test_tabular_auto.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/test.R 3 | \name{test_tabular_auto} 4 | \alias{test_tabular_auto} 5 | \title{test for contingency table} 6 | \usage{ 7 | test_tabular_auto(x, y) 8 | } 9 | \arguments{ 10 | \item{x}{vector} 11 | 12 | \item{y}{another vector} 13 | } 14 | \value{ 15 | a list with two components: p.value and method 16 | } 17 | \description{ 18 | Compute a chisq.test, a chisq.test with correction of continuity 19 | or a fisher test as appropriate 20 | } 21 | \author{ 22 | Dan Chaltiel, David Hajage 23 | } 24 | -------------------------------------------------------------------------------- /man/transpose_crosstable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/pivot.R 3 | \name{transpose_crosstable} 4 | \alias{transpose_crosstable} 5 | \alias{t.crosstable} 6 | \title{Transpose a crosstable} 7 | \usage{ 8 | transpose_crosstable(x) 9 | 10 | \method{t}{crosstable}(x) 11 | } 12 | \arguments{ 13 | \item{x}{a crosstable} 14 | } 15 | \value{ 16 | a tibble of class \code{transposed_crosstable} 17 | } 18 | \description{ 19 | Pivot a crosstable so the \code{label} column is swapped with the \code{by} row. 20 | This requires the \code{variable} column to be the same for every data column, like when all columns are numeric of when all columns are factors with the same levels 21 | } 22 | \examples{ 23 | ct = crosstable(mtcars2, c(mpg, drat, wt, qsec), by=am) 24 | ct \%>\% t() \%>\% as_flextable() 25 | ct2 = crosstable(mtcars2, c(mpg, drat, wt, qsec), by=c(am, vs)) 26 | ct2 \%>\% t() \%>\% as_flextable() 27 | } 28 | -------------------------------------------------------------------------------- /man/write_and_open.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/officer.R 3 | \name{write_and_open} 4 | \alias{write_and_open} 5 | \title{Alternative to default \code{officer} print() function. Write the file and try to open it right away.} 6 | \usage{ 7 | write_and_open(doc, docx.file) 8 | } 9 | \arguments{ 10 | \item{doc}{the docx object} 11 | 12 | \item{docx.file}{the name of the target file. If missing or NULL, the doc will open in a temporary file.} 13 | } 14 | \value{ 15 | Nothing, called for its side effects 16 | } 17 | \description{ 18 | As it tests if the file is writable, this function also prevents \code{officer:::print.rdocx()} to abort the RStudio session. 19 | } 20 | \examples{ 21 | library(officer) 22 | library(crosstable) 23 | mytable = crosstable(mtcars2) 24 | doc = read_docx() \%>\% 25 | body_add_crosstable(mytable) 26 | 27 | write_and_open(doc) 28 | \dontrun{ 29 | write_and_open(doc, "example.docx") 30 | } 31 | } 32 | \author{ 33 | Dan Chaltiel 34 | } 35 | -------------------------------------------------------------------------------- /pkgdown/extra.css: -------------------------------------------------------------------------------- 1 | .table td { 2 | padding: 0 !important; 3 | } 4 | 5 | h1 img { 6 | height: 175px !important; 7 | } 8 | 9 | .table { 10 | display: table !important; 11 | margin: 0 auto 40px auto !important; 12 | width: auto !important; 13 | } 14 | 15 | 16 | 17 | 18 | 19 | /*Modal images*/ 20 | 21 | #zz_frame::before { 22 | content: ''; 23 | top: 0; 24 | left: 0; 25 | width: 100%; 26 | height: 100%; 27 | position: fixed; 28 | background: rgba(0,0,0,0.85); 29 | z-index: -1; 30 | } 31 | #zz_frame { 32 | top: 0; 33 | left: 0; 34 | width: 100%; 35 | height: 100%; 36 | position: fixed; 37 | text-align: center; 38 | z-index: 99999; 39 | } 40 | #zz_frame .zz_close { 41 | color: #fff; 42 | position: fixed; 43 | right: 10px; 44 | top: 10px; 45 | font-size: 26px; 46 | background: transparent; 47 | border: 0; 48 | border-radius: 50%; 49 | cursor: pointer; 50 | } 51 | #zz_frame img { 52 | max-height: 95%; 53 | max-width: 95%; 54 | box-shadow: 0px 0px 20px 1px rgb(0,0,0); 55 | } 56 | 57 | #zz_helper { 58 | height: 100%; 59 | vertical-align: middle; 60 | display: inline-block; 61 | } 62 | 63 | .zz_image { 64 | cursor: pointer; 65 | } -------------------------------------------------------------------------------- /pkgdown/extra.js: -------------------------------------------------------------------------------- 1 | /* 2 | Modal image viewer 3 | Adapted by Dan Chaltiel from https://www.jqueryscript.net/lightbox/image-modal-zoom-in-out.html 4 | */ 5 | (function ($) { 6 | $(function () { 7 | //console.log('image-popup loaded') 8 | $('.section img').addClass('zz_image') 9 | 10 | var body = $('body'); 11 | var container = $('
'); 12 | var helper = $(''); 13 | var close_btn = $(''); 14 | var button_zoom = $('
'); 15 | var image = $(''); 16 | 17 | $('.zz_image').click( function(e) { 18 | e.preventDefault(); 19 | uri = $(this).attr('src'); 20 | image.attr('src', uri); 21 | 22 | container.append(helper); 23 | container.append(image); 24 | container.append(close_btn); 25 | body.append(container); 26 | }); 27 | 28 | $('body').on('click', '.zz_close, #zz_frame, #zz_frame img', function(e) { 29 | $('#zz_frame').remove(); 30 | }) 31 | 32 | }); 33 | })(jQuery); 34 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /revdep/.gitignore: -------------------------------------------------------------------------------- 1 | checks 2 | library 3 | checks.noindex 4 | library.noindex 5 | cloud.noindex 6 | data.sqlite 7 | *.html 8 | -------------------------------------------------------------------------------- /revdep/README.md: -------------------------------------------------------------------------------- 1 | # Platform 2 | 3 | |field |value | 4 | |:--------|:-----------------------------------------------------| 5 | |version |R version 4.4.1 (2024-06-14 ucrt) | 6 | |os |Windows 10 x64 (build 19045) | 7 | |system |x86_64, mingw32 | 8 | |ui |RStudio | 9 | |language |(EN) | 10 | |collate |French_France.utf8 | 11 | |ctype |French_France.utf8 | 12 | |tz |Europe/Paris | 13 | |date |2024-11-01 | 14 | |rstudio |2024.09.0+375 Cranberry Hibiscus (desktop) | 15 | |pandoc |2.14.2 @ C:\Users\Dan\AppData\Local\Pandoc\pandoc.exe | 16 | 17 | # Dependencies 18 | 19 | |package |old |new |Δ | 20 | |:-----------------|:-------|:-------|:--| 21 | |crosstable |0.8.0 |0.8.1 |* | 22 | |askpass |1.2.1 |1.2.1 | | 23 | |backports |1.5.0 |1.5.0 | | 24 | |base64enc |0.1-3 |0.1-3 | | 25 | |bslib |0.8.0 |0.8.0 | | 26 | |cachem |1.1.0 |1.1.0 | | 27 | |checkmate |2.3.2 |2.3.2 | | 28 | |cli |3.6.3 |3.6.3 | | 29 | |cpp11 |0.5.0 |0.5.0 | | 30 | |data.table |1.16.2 |1.16.2 | | 31 | |digest |0.6.37 |0.6.37 | | 32 | |dplyr |1.1.4 |1.1.4 | | 33 | |evaluate |1.0.1 |1.0.1 | | 34 | |fansi |1.0.6 |1.0.6 | | 35 | |fastmap |1.2.0 |1.2.0 | | 36 | |flextable |0.9.7 |0.9.7 | | 37 | |fontawesome |0.5.2 |0.5.2 | | 38 | |fontBitstreamVera |0.1.1 |0.1.1 | | 39 | |fontLiberation |0.1.0 |0.1.0 | | 40 | |fontquiver |0.2.1 |0.2.1 | | 41 | |forcats |1.0.0 |1.0.0 | | 42 | |fs |1.6.5 |1.6.5 | | 43 | |gdtools |0.4.0 |0.4.0 | | 44 | |generics |0.1.3 |0.1.3 | | 45 | |glue |1.8.0 |1.8.0 | | 46 | |highr |0.11 |0.11 | | 47 | |htmltools |0.5.8.1 |0.5.8.1 | | 48 | |jquerylib |0.1.4 |0.1.4 | | 49 | |jsonlite |1.8.9 |1.8.9 | | 50 | |knitr |1.48 |1.48 | | 51 | |lifecycle |1.0.4 |1.0.4 | | 52 | |magrittr |2.0.3 |2.0.3 | | 53 | |memoise |2.0.1 |2.0.1 | | 54 | |mime |0.12 |0.12 | | 55 | |officer |0.6.7 |0.6.7 | | 56 | |openssl |2.2.2 |2.2.2 | | 57 | |pillar |1.9.0 |1.9.0 | | 58 | |pkgconfig |2.0.3 |2.0.3 | | 59 | |purrr |1.0.2 |1.0.2 | | 60 | |R6 |2.5.1 |2.5.1 | | 61 | |ragg |1.3.3 |1.3.3 | | 62 | |rappdirs |0.3.3 |0.3.3 | | 63 | |Rcpp |1.0.13 |1.0.13 | | 64 | |rlang |1.1.4 |1.1.4 | | 65 | |rmarkdown |2.28 |2.28 | | 66 | |sass |0.4.9 |0.4.9 | | 67 | |stringi |1.8.4 |1.8.4 | | 68 | |stringr |1.5.1 |1.5.1 | | 69 | |sys |3.4.3 |3.4.3 | | 70 | |systemfonts |1.1.0 |1.1.0 | | 71 | |textshaping |0.4.0 |0.4.0 | | 72 | |tibble |3.2.1 |3.2.1 | | 73 | |tidyr |1.3.1 |1.3.1 | | 74 | |tidyselect |1.2.1 |1.2.1 | | 75 | |tinytex |0.53 |0.53 | | 76 | |utf8 |1.2.4 |1.2.4 | | 77 | |uuid |1.2-1 |1.2-1 | | 78 | |vctrs |0.6.5 |0.6.5 | | 79 | |withr |3.0.2 |3.0.2 | | 80 | |xfun |0.49 |0.49 | | 81 | |xml2 |1.3.6 |1.3.6 | | 82 | |yaml |2.3.10 |2.3.10 | | 83 | |zip |2.3.1 |2.3.1 | | 84 | 85 | # Revdeps 86 | 87 | -------------------------------------------------------------------------------- /revdep/cran.md: -------------------------------------------------------------------------------- 1 | ## revdepcheck results 2 | 3 | We checked 2 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. 4 | 5 | * We saw 0 new problems 6 | * We failed to check 0 packages 7 | 8 | -------------------------------------------------------------------------------- /revdep/failures.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /revdep/problems.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # This file is part of the standard setup for testthat. 2 | # It is recommended that you do not modify it. 3 | # 4 | # Where should you do additional test configuration? 5 | # Learn more about the roles of various files in: 6 | # * https://r-pkgs.org/tests.html 7 | # * https://testthat.r-lib.org/reference/test_package.html#special-files 8 | 9 | library(testthat) 10 | library(crosstable) 11 | 12 | test_check("crosstable") 13 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/crosstable.md: -------------------------------------------------------------------------------- 1 | # Named ellipsis 2 | 3 | Arguments in `...` must be passed by position, not name. 4 | x Problematic arguments: 5 | * foo = vs 6 | * bar = am 7 | 8 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/methods.md: -------------------------------------------------------------------------------- 1 | # transpose works 2 | 3 | Code 4 | ct2 = t(ct) 5 | class(ct2) 6 | Output 7 | [1] "transposed_crosstable" "crosstable" "tbl_df" 8 | [4] "tbl" "data.frame" 9 | Code 10 | ct2 11 | Output 12 | # A tibble: 40 x 6 13 | .id letter variable `the X` `the Y` `the Z` 14 | 15 | 1 a a Min / Max -0.6 / 1.5 -0.2 / 1.4 -0.6 / 2.4 16 | 2 a a Med [IQR] 0.9 [0.1;1.2] 0.4 [0.1;0.9] 0.5 [-0.05;1.4] 17 | 3 a a Mean (std) 0.6 (1.1) 0.5 (0.8) 0.8 (1.5) 18 | 4 a a N (NA) 3 (0) 3 (0) 3 (0) 19 | 5 b b Min / Max 0.2 / 0.8 -0.6 / -0.1 -0.7 / -0.04 20 | 6 b b Med [IQR] 0.4 [0.3;0.6] -0.3 [-0.4;-0.2] -0.1 [-0.4;-0.1] 21 | 7 b b Mean (std) 0.5 (0.3) -0.3 (0.3) -0.3 (0.4) 22 | 8 b b N (NA) 3 (0) 3 (0) 3 (0) 23 | 9 c c Min / Max -0.8 / 0.1 0.3 / 0.7 0.6 / 1.2 24 | 10 c c Med [IQR] -0.6 [-0.7;-0.3] 0.4 [0.4;0.5] 0.7 [0.7;0.9] 25 | # i 30 more rows 26 | Code 27 | af(ct2)$header$dataset 28 | Output 29 | letter variable the X the Y the Z 30 | 1 letter variable Columns Columns Columns 31 | 2 letter variable the X the Y the Z 32 | 33 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/officer.md: -------------------------------------------------------------------------------- 1 | # Officers warnings and errors 2 | 3 | `...` must be empty. 4 | x Problematic arguments: 5 | * foo = 1 6 | * fun = mean 7 | * ..3 = 5 8 | i Did you forget to name an argument? 9 | 10 | # gt is working 11 | 12 | `as_gt()` is not implemented for multi-by crosstables yet. 13 | 14 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/pivot.md: -------------------------------------------------------------------------------- 1 | # pivot 2 | 3 | Code 4 | pivot_crosstable(ct) 5 | Output 6 | # A tibble: 3 x 6 7 | .id label A B C `NA` 8 | 9 | 1 x the X 11 (44.00%) 7 (28.00%) 7 (28.00%) 5 10 | 2 y the Y 6 (20.00%) 17 (56.67%) 7 (23.33%) 0 11 | 3 z the Z 10 (47.62%) 3 (14.29%) 8 (38.10%) 9 12 | Code 13 | pivot_crosstable(ct) %>% af(T) %>% { 14 | .$header$dataset 15 | } 16 | Output 17 | .id label A B C NA 18 | 1 .id label Variable Variable Variable Variable 19 | 2 .id label A B C NA 20 | Code 21 | pivot_crosstable(ct) %>% af(by_header = "foobar") 22 | Output 23 | a flextable object. 24 | col_keys: `label`, `A`, `B`, `C`, `NA` 25 | header has 2 row(s) 26 | body has 3 row(s) 27 | original dataset sample: 28 | .id label A B C NA 29 | 1 x the X 11 (44.00%) 7 (28.00%) 7 (28.00%) 5 30 | 2 y the Y 6 (20.00%) 17 (56.67%) 7 (23.33%) 0 31 | 3 z the Z 10 (47.62%) 3 (14.29%) 8 (38.10%) 9 32 | 33 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/quick_surv.md: -------------------------------------------------------------------------------- 1 | # survival POC 2 | 3 | Code 4 | df = data.frame(time = c(71.1, 75.7, 78.7, 79, 95.1, 108, 120.1, 120.3, 121, 5 | 140.8, 145, 146.7, 160, 160, 167.6, 167.6, 225, 258, 275.8, 275.8, 275.8, 301, 6 | 304, 318, 350, 351, 360, 360, 400, 440, 460, 472), event = rep(rep(c(1, 0), 6), 7 | c(6L, 1L, 2L, 1L, 1L, 1L, 2L, 7L, 1L, 3L, 1L, 6L)), group = rep(c("B", "A", "B", 8 | "A", "B", "A", "B", "A", "B", "A", "B"), c(9L, 1L, 1L, 1L, 2L, 3L, 1L, 1L, 7L, 9 | 2L, 4L))) 10 | df$time = round(df$time) 11 | df$surv = survival::Surv(df$time, df$event) 12 | fit = survival::survfit(surv ~ group, data = df) 13 | times = sort(unique(fit$time)) 14 | x = summary(fit, times = times, extend = TRUE) 15 | a = data.frame(strata = x$strata, time = x$time, n.risk = x$n.risk, n.event = x$ 16 | n.event, surv = x$surv) 17 | a %>% dplyr::filter(strata == "group=B") %>% dplyr::filter(time == 141) 18 | Output 19 | strata time n.risk n.event surv 20 | 1 group=B 141 15 0 0.6640625 21 | 22 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/selection.md: -------------------------------------------------------------------------------- 1 | # crosstable limit tests: deprecated features 2 | 3 | Code 4 | crosstable(mtcars2, am, cyl) %>% invisible() 5 | Condition 6 | Warning: 7 | The `...` argument of `crosstable()` is deprecated as of crosstable 0.2.0. 8 | i Please use the `cols` argument instead. 9 | x Bad : `crosstable(mtcars2, am, cyl, ...)` 10 | v Good: `crosstable(mtcars2, c(am, cyl), ...)` 11 | Code 12 | crosstable(mtcars2, c(am, cyl), hp) %>% invisible() 13 | Condition 14 | Warning: 15 | The `...` argument of `crosstable()` is deprecated as of crosstable 0.2.0. 16 | i Please use the `cols` argument instead. 17 | x Bad : `crosstable(mtcars2, c(am, cyl), hp, ...)` 18 | v Good: `crosstable(mtcars2, c(am, cyl, hp), ...)` 19 | Code 20 | crosstable(mtcars2, am, c(hp, mpg)) %>% invisible() 21 | Condition 22 | Warning: 23 | The `...` argument of `crosstable()` is deprecated as of crosstable 0.2.0. 24 | i Please use the `cols` argument instead. 25 | x Bad : `crosstable(mtcars2, am, c(hp, mpg), ...)` 26 | v Good: `crosstable(mtcars2, c(am, hp, mpg), ...)` 27 | Code 28 | crosstable(mtcars2, c(am, cyl), c(hp, mpg)) %>% invisible() 29 | Condition 30 | Warning: 31 | The `...` argument of `crosstable()` is deprecated as of crosstable 0.2.0. 32 | i Please use the `cols` argument instead. 33 | x Bad : `crosstable(mtcars2, c(am, cyl), c(hp, mpg), ...)` 34 | v Good: `crosstable(mtcars2, c(am, cyl, hp, mpg), ...)` 35 | Code 36 | crosstable(mtcars2, c(am, cyl), c(hp, mpg), c(hp, mpg)) %>% invisible() 37 | Condition 38 | Warning: 39 | The `...` argument of `crosstable()` is deprecated as of crosstable 0.2.0. 40 | i Please use the `cols` argument instead. 41 | x Bad : `crosstable(mtcars2, c(am, cyl), c(hp, mpg), c(hp, mpg), ...)` 42 | v Good: `crosstable(mtcars2, c(am, cyl, hp, mpg), ...)` 43 | 44 | # crosstable limit tests: errors 45 | 46 | Predicate must return `TRUE` or `FALSE`, not a string. 47 | 48 | --- 49 | 50 | object 'B' not found 51 | 52 | --- 53 | 54 | Code 55 | crosstable(iris2, ~.x, by = "Species") 56 | Condition 57 | Error in `select()`: 58 | ! Predicate must return `TRUE` or `FALSE`, not a object. 59 | 60 | --- 61 | 62 | Code 63 | crosstable(iris2, ~ c(is.numeric(.x), is.numeric(.x)), by = "Species") 64 | Condition 65 | Error in `select()`: 66 | ! Predicate must return `TRUE` or `FALSE`, not a logical vector. 67 | 68 | -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_crosstables_double_with_effects.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_crosstables_double_with_effects.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_crosstables_double_with_effects_new.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_crosstables_double_with_effects_new.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_crosstables_helpers.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_crosstables_helpers.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_crosstables_simple.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_crosstables_simple.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_crosstables_simple_new.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_crosstables_simple_new.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_crosstables_triple.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_crosstables_triple.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_crosstables_triple_new.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_crosstables_triple_new.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_utils_functions.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_utils_functions.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_utils_functions_are_ok_too.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_utils_functions_are_ok_too.docx -------------------------------------------------------------------------------- /tests/testthat/docx/4-officer/snap_utils_functions_new.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/docx/4-officer/snap_utils_functions_new.docx -------------------------------------------------------------------------------- /tests/testthat/helper-init_dataset.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Options and packages ------------------------------------------------------------------------ 4 | 5 | Sys.setenv(LANGUAGE = "en") 6 | Sys.setenv(TZ='Europe/Paris') 7 | Sys.setenv(TESTTHAT_NCPUS =4) 8 | options( 9 | encoding="UTF-8", 10 | # width = 200, 11 | # warn=0, #default, stacks 12 | warn=1, #immediate. =TRUE 13 | Ncpus=4, 14 | # warn=2, #error 15 | # warnPartialMatchArgs=TRUE, 16 | # warnPartialMatchAttr=TRUE, 17 | # warnPartialMatchDollar=TRUE, 18 | stringsAsFactors=FALSE, 19 | # conflicts.policy="depends.ok", 20 | dplyr.summarise.inform=FALSE, 21 | tidyverse.quiet=TRUE, 22 | tidyselect_verbosity ="verbose",#quiet or verbose 23 | lifecycle_verbosity="warning", #NULL, "quiet", "warning" or "error" 24 | # lifecycle_verbosity="verbose", 25 | testthat.progress.max_fails = 50 26 | ) 27 | crosstable_reset_options(quiet=TRUE) 28 | crosstable_options( 29 | verbosity_autotesting="quiet", 30 | verbosity_na_cols="verbose", 31 | ) 32 | # rlang::global_entrace() 33 | # prettycode::prettycode() 34 | 35 | 36 | #'@source https://stackoverflow.com/a/52066708/3888000 37 | shhh = function(expr) suppressPackageStartupMessages(suppressWarnings(expr)) 38 | shhh(library(dplyr)) 39 | shhh(library(officer)) 40 | 41 | 42 | # Dataset ------------------------------------------------------------------------------------- 43 | 44 | set.seed(1234) 45 | mtcars3 = as_tibble(mtcars2) 46 | mtcars3$cyl[1:5] = NA 47 | mtcars3$vs[5:12] = NA 48 | mtcars3$cyl3 = mtcars3$cyl==3 49 | mtcars3$cyl6 = mtcars3$cyl==6 50 | mtcars3$dummy = "dummy" 51 | mtcars3$dummy_na = NA 52 | mtcars3$dummy_na2 = NA 53 | mtcars3$dummy_num_vs = ifelse(mtcars3$vs=="vshaped", 0, stats::rnorm(15)) 54 | mtcars3$dummy2 = mtcars3$dummy 55 | mtcars3$dummy2[5:12] = NA 56 | mtcars3$test = stats::rbinom(nrow(mtcars3), 1, 0.5) %>% factor(labels = c("A","B")) 57 | mtcars3$surv = survival::Surv(mtcars3$disp, mtcars3$am=="manual") %>% set_label("Dummy survival (disp/am)") 58 | # mtcars3$my_date = as.Date(mtcars2$hp , origin="2010-01-01") %>% set_label("Some nonsense date") 59 | # mtcars3$my_posix = as.POSIXct(mtcars2$qsec*3600*24 , origin="2010-01-01") %>% set_label("Date+time") 60 | mtcars3$diff = difftime(mtcars3$hp_date, mtcars3$qsec_posix, units="days") %>% set_label("Difftime hp_date-qsec_posix (days)") 61 | 62 | 63 | # Functions ----------------------------------------------------------------------------------- 64 | 65 | v = utils::View 66 | iris2names = c(SL="Sepal.Length", SW="Sepal.Width", PL="Petal.Length", PW="Petal.Width", Sp="Species") 67 | iris2_num = iris2 %>% select(-Species) 68 | 69 | 70 | expect_cross = function(x, xnames, byname, dim, regex){ 71 | # expect=match.arg(expect) 72 | # if(expect=="nothing"){ 73 | # x=eval(expr, envir=caller_env()) 74 | # } 75 | # else if(expect=="silent") 76 | # x=expect_silent(expr) 77 | # else if(expect=="warning") 78 | # x=expect_warning(expr, regex) 79 | # else 80 | # x=expect_error(expr, regex) 81 | expect_s3_class(x, c("data.frame", "crosstable")) 82 | expect_equal(dim, dim(x)) 83 | expect_equal(byname, unname(attr(x, "by"))) 84 | 85 | if(all(xnames %in% names(iris2names))) 86 | expect_equal(unname(iris2names[xnames]), unique(as.character(x$.id))) 87 | else 88 | expect_equal(unname(xnames), unique(x$.id)) 89 | } 90 | 91 | expect_cross_bak = function(expr, xnames, byname, dim, expect=c("nothing", "silent", "warning", "error"), regex){ 92 | expect=match.arg(expect) 93 | if(expect=="nothing"){ 94 | x=eval(expr, envir=caller_env()) 95 | } 96 | else if(expect=="silent") 97 | x=expect_silent(expr) 98 | else if(expect=="warning") 99 | x=expect_warning(expr, regex) 100 | else 101 | x=expect_error(expr, regex) 102 | expect_s3_class(x, c("data.frame", "crosstable")) 103 | expect_equal(dim, dim(x)) 104 | expect_equal(byname, unname(attr(x, "by"))) 105 | 106 | if(all(xnames %in% names(iris2names))) 107 | expect_equal(unname(iris2names[xnames]), unique(as.character(x$.id))) 108 | else 109 | expect_equal(unname(xnames), unique(x$.id)) 110 | } 111 | 112 | snapshot_review_bg = function(...){ 113 | # brw = function(url) .Call("rs_browseURL", url, PACKAGE="(embedding)") 114 | brw = Sys.getenv("R_BROWSER") 115 | callr::r_bg(function() testthat::snapshot_review(...), 116 | package=TRUE, 117 | env = c(R_BROWSER = brw)) 118 | } 119 | 120 | expect_warning2 = function(object, ...) { 121 | rtn = testthat::expect_warning(object, ...) 122 | if (inherits(object, "condition")) { 123 | attr(rtn, "object") = attr(object, "object") 124 | } else{ 125 | attr(rtn, "object") = object 126 | } 127 | rtn 128 | } 129 | 130 | compare = function (x, y, x_arg=caller_arg(x), y_arg=caller_arg(y), len_max=Inf, ...) { 131 | x_arg = stringr::str_trunc(x_arg, width=len_max) 132 | y_arg = stringr::str_trunc(y_arg, width=len_max) 133 | waldo::compare(x, y, x_arg=x_arg, y_arg=y_arg, ...) 134 | } 135 | 136 | 137 | cli::cli_inform(c(v="Initializer {.file helper-init_dataset.R} loaded", 138 | i="is_testing={is_testing()}, is_parallel={is_parallel()}")) 139 | -------------------------------------------------------------------------------- /tests/testthat/test-compact.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Purrr compatibility ------------------------------------------------------------------------- 4 | 5 | test_that("Compact method error if list without purrr", { 6 | ll=list(a = "a", b = NULL, c = integer(0), d = NA, e = list()) 7 | ct=crosstable(iris) 8 | expect_silent(purrr::compact(ll)) 9 | expect_error(compact(ll), class="compact_notfound_error") 10 | expect_error(ct_compact(ll), class="ct_compact_notfound_error") 11 | lifecycle::expect_deprecated(compact(ct)) 12 | lifecycle::expect_deprecated(compact(as.data.frame(ct), name_from="label")) 13 | }) 14 | 15 | test_that("Compact method OK with purrr", { 16 | ll=list(a = "a", b = NULL, c = integer(0), d = NA, e = list()) 17 | shhh(library(purrr)) 18 | compact=crosstable::compact 19 | expect_identical(compact(ll), list(a="a",d=NA)) 20 | 21 | x=sloop::s3_dispatch(compact(ll)) 22 | expect_true("compact.list" %in% x$method) 23 | x=sloop::s3_dispatch(compact(crosstable(iris))) 24 | expect_true("compact.crosstable" %in% x$method) 25 | }) 26 | 27 | # Method checks ----------------------------------------------------------- 28 | 29 | test_that("Compact method OK with data.frame", { 30 | df=iris[c(1:5,51:55,101:105),] 31 | expect_silent(ct_compact(df, name_from="Species", name_to="Petal.Length", rtn_flextable=TRUE)) 32 | 33 | x=sloop::s3_dispatch(ct_compact(df, name_from="Species")) 34 | expect_true("ct_compact.data.frame" %in% x$method) 35 | 36 | expect_snapshot({ 37 | ct_compact(df, name_from="Species") 38 | ct_compact(df, name_from="Species", name_to="Petal.Length") 39 | df$Species2 = substr(df$Species, 1, 1) 40 | ct_compact(df, name_from="Species", name_to="Petal.Length", wrap_cols="Species2") 41 | }) 42 | }) 43 | 44 | test_that("Compact method OK with crosstable", { 45 | ct=crosstable(mtcars2, disp+hp+cyl+am~vs) 46 | expect_snapshot({ 47 | ct_compact(ct) 48 | ct_compact(ct, name_from=".id") 49 | }) 50 | 51 | x=sloop::s3_dispatch(ct_compact(ct)) 52 | expect_true("ct_compact.crosstable" %in% x$method) 53 | }) 54 | 55 | 56 | test_that("Compacting inside or outside as_flextable.crosstable gives the same result", { 57 | rlang::local_options(tidyselect_verbosity = "quiet") 58 | ct1 = crosstable(esoph, by="tobgp", test = TRUE) %>% suppressWarnings() %>% ct_compact() 59 | expect_equal(dim(ct1), c(22,6)) 60 | expect_s3_class(ct1, c("data.frame", "crosstable", "compacted_crosstable")) 61 | 62 | ct2 = crosstable(esoph, by="tobgp", test = TRUE) 63 | expect_identical(as_flextable(ct1), as_flextable(ct2, compact=TRUE)) 64 | }) 65 | 66 | 67 | test_that("Compact method OK with as_flextable()", { 68 | 69 | ct = mtcars2 %>% 70 | apply_labels(am="Engine") %>% 71 | crosstable(c(am, vs)) 72 | 73 | ft1 = ct %>% af(compact=FALSE) 74 | expect_setequal(ft1$body$dataset$.id, c("am", "vs")) 75 | expect_setequal(ft1$body$dataset$label, "Engine") 76 | expect_equal(ft1$body$dataset$variable, c("auto", "manual", "straight", "vshaped")) 77 | expect_equal(as.character(ft1$header$dataset), c("label", "variable", "value")) 78 | 79 | ft2 = ct %>% af(compact=TRUE) 80 | expect_null(ft2$body$dataset$.id) 81 | expect_null(ft2$body$dataset$label) 82 | expect_equal(ft2$body$dataset$variable, 83 | c("Engine", "auto", "manual", "Engine", "straight", "vshaped")) 84 | expect_equal(as.character(ft2$header$dataset), c("variable", "value")) 85 | 86 | }) 87 | 88 | 89 | 90 | # Misc flextable ---------------------------------------------------------- 91 | 92 | 93 | test_that("Flextable: by_header", { 94 | rlang::local_options(tidyselect_verbosity = "quiet") 95 | ct = crosstable(esoph, by="tobgp") 96 | ft=ct %>% as_flextable(by_header="blabla") 97 | 98 | expect_setequal(ft$header$dataset[1,3:5], "blabla") 99 | }) 100 | 101 | test_that("Flextable: show_test_name", { 102 | ct = crosstable(esoph, by="tobgp", test = TRUE) 103 | ft1=ct %>% as_flextable(show_test_name=TRUE) #default 104 | expect_match(ft1$body$dataset$test[1], "\\n") 105 | ft2=ct %>% as_flextable(show_test_name=FALSE) 106 | expect_match(ft2$body$dataset$test[1], ".*?\\d+(\\.\\d+)?\\s+$") 107 | }) 108 | 109 | test_that("Flextable: keepid", { 110 | ct = crosstable(esoph, by="tobgp", test = TRUE) 111 | ft1=ct %>% as_flextable(keep_id=FALSE) #default 112 | ft2=ct %>% as_flextable(keep_id=TRUE) 113 | expect_false(".id" %in% ft1$body$col_keys) 114 | expect_true(".id" %in% ft2$body$col_keys) 115 | }) 116 | -------------------------------------------------------------------------------- /tests/testthat/test-crosstable.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # By Nothing --------------------------------------------------------- 5 | test_that("numeric+factor+surv by nothing", { 6 | x1=crosstable(mtcars3, c(am,mpg,cyl,surv)) 7 | x1 %>% as_flextable() 8 | expect_true(is.crosstable(x1)) 9 | expect_equal(dim(x1), c(38,4)) 10 | expect_equal(sum(is.na(x1)), 1) 11 | 12 | x2=crosstable(mtcars3, c(am,mpg,cyl,surv), times=c(0,100,200,400), followup=TRUE) 13 | x2 %>% as_flextable() 14 | expect_true(is.crosstable(x2)) 15 | expect_equal(dim(x2), c(16,4)) 16 | expect_equal(sum(is.na(x2)), 1) 17 | }) 18 | 19 | 20 | test_that('Contains both `NA` and "NA"', { 21 | # "'NA'" is overkill to test 22 | x = data.frame(a = as_factor(c("zzz", "zzz", "NA", "NA", NA, NA, "aaa", "aaa")), 23 | b = rep(1:2, 4)) 24 | x$a %>% levels 25 | 26 | crosstable(x, a) %>% 27 | pull(variable) %>% 28 | expect_identical(c("zzz", "aaa", "\"NA\"", "NA")) 29 | 30 | crosstable(x, a, by=b) %>% 31 | pull(variable) %>% 32 | expect_identical(c("zzz", "aaa", "\"NA\"", "NA")) 33 | }) 34 | 35 | 36 | # Arguments ----------------------------------------------------------------------------------- 37 | 38 | 39 | test_that('`remove_zero_percent` works', { 40 | crosstable_options(remove_zero_percent=TRUE, .local=TRUE) 41 | a = crosstable(mtcars2, cyl, by=vs) 42 | expect_true(any(a=="0")) 43 | crosstable_options(remove_zero_percent=FALSE, .local=TRUE) 44 | a = crosstable(mtcars2, cyl, by=vs) 45 | expect_false(any(a=="0")) 46 | a = crosstable(mtcars2, cyl, by=vs, remove_zero_percent=TRUE) 47 | expect_true(any(a=="0")) 48 | }) 49 | 50 | # Crossing difftime ------------------------------------------------------- 51 | 52 | test_that("difftime is OK", { 53 | x1=crosstable(mtcars3, diff) 54 | expect_equal(dim(x1), c(4,4)) 55 | expect_equal(sum(is.na(x1)), 0) 56 | x2=crosstable(mtcars3, diff, by=disp) 57 | expect_equal(dim(x2), c(1,4)) 58 | expect_equal(sum(is.na(x2)), 0) 59 | x3=crosstable(mtcars3, diff, by=cyl) 60 | expect_equal(dim(x3), c(4,7)) 61 | expect_equal(sum(is.na(x3)), 0) 62 | }) 63 | 64 | test_that("difftime is OK also", { 65 | set.seed(42) 66 | x1 = tibble( 67 | h = rpois(10, 10), m = rpois(10, 30), 68 | hm = lubridate::hm(paste0(h,":",m)), 69 | hms = hms::hms(hours=h, minutes=m), 70 | hms2 = hms::hms(hours=h*20, minutes=m), 71 | ) 72 | class(x1$hm) #Period 73 | class(x1$hms)#hms + difftime 74 | ct = crosstable(x1, starts_with("hm")) 75 | expect_equal(ct$value[2], "11H 28M 30S [9H 34M 15S;14H 3M 15S]") 76 | }) 77 | 78 | 79 | # Warnings ---------------------------------------------------------------- 80 | 81 | test_that("Warn: numeric+factor by numeric: ", { 82 | expect_warning(crosstable(mtcars3, c(mpg, cyl), by=disp), 83 | class="crosstable_wrong_col_class_by_warning") 84 | expect_warning(crosstable(mtcars3, c(mpg, surv), by=disp, effect=T), 85 | class="crosstable_wrong_col_class_by_warning") 86 | expect_warning(crosstable(mtcars3, c(mpg, cyl, surv), by=disp, effect=T), 87 | class="crosstable_wrong_col_class_by_warning") 88 | 89 | }) 90 | 91 | 92 | test_that('Warn: contains only `NA`', { 93 | crosstable(mtcars3, dummy_na) %>% 94 | expect_warning(class='crosstable_all_na_warning') %>% 95 | expect_warning(class='crosstable_empty_warning') 96 | }) 97 | 98 | test_that('Warn: Duplicate columns are removed from `cols`', { 99 | rlang::local_options(crosstable_verbosity_duplicate_cols="verbose") 100 | crosstable(mtcars3, c(mpg, gear, am, vs), by=c(am, vs)) %>% 101 | expect_warning(class="crosstable_duplicate_cols_warning") 102 | }) 103 | 104 | test_that('Warn: Total in rows when by is NULL', { 105 | crosstable(mtcars2, c(mpg, wt), total="row") %>% 106 | expect_warning(class='crosstable_totalrow_bynull') 107 | crosstable(mtcars2, mpg+wt~1, total="row") %>% 108 | expect_warning(class='crosstable_totalrow_bynull') 109 | }) 110 | 111 | test_that("Warn: Deprecation: moystd", { 112 | lifecycle::expect_deprecated(crosstable(mtcars2, disp, funs=moystd)) 113 | }) 114 | 115 | 116 | 117 | # Errors ------------------------------------------------------------------ 118 | 119 | 120 | test_that("BY class check", { 121 | #no by survival 122 | expect_error(crosstable(mtcars3, vs, by=surv, times=c(0,100,200,400)), 123 | class="crosstable_wrong_byclass_error") 124 | #no by date 125 | mtcars3$dummy_posix = as.Date(mtcars3$disp, origin="2020-01-01") %>% as.POSIXct 126 | expect_error(crosstable(mtcars3, vs, by=dummy_posix), 127 | class="crosstable_wrong_byclass_error") 128 | }) 129 | 130 | test_that("Functions should return scalar", { 131 | crosstable(mtcars2, c(mpg, wt), by=am, funs=c("square"=function(xx) xx^2)) %>% 132 | expect_error(class="crosstable_summary_not_scalar") 133 | crosstable(mtcars2, c(mpg, wt), by=am, funs=c(" "=function(xx) xx^2)) %>% 134 | expect_error(class="crosstable_summary_not_scalar") 135 | }) 136 | 137 | test_that("Named ellipsis", { 138 | expect_snapshot_error(crosstable(mtcars3, foo=vs, bar=am)) 139 | }) 140 | 141 | -------------------------------------------------------------------------------- /tests/testthat/test-effects.R: -------------------------------------------------------------------------------- 1 | #snapshot_review('effects') 2 | 3 | 4 | # Categorical variables --------------------------------------------------- 5 | 6 | test_that("Effects: categorical variables", { 7 | set.seed(0) 8 | e_args = crosstable_effect_args() 9 | 10 | # e_args$effect_tabular = effect_odds_ratio (default) 11 | x=crosstable(mtcars3, am, by=vs, effect=T, effect_args=e_args) 12 | expect_match(x$effect[1], "0.19 [0.02 to 1.11]", fixed=TRUE) 13 | 14 | e_args$effect_tabular = effect_relative_risk 15 | x = crosstable(mtcars3, am~vs, effect=T, effect_args=e_args) %>% 16 | expect_warning2(class="crosstable_effect_error_warning") 17 | expect_match(attr(x, "obj")$effect[1], "0.56 [CI error]", fixed=TRUE) 18 | x = crosstable(mtcars3, am~fct_rev(vs), effect=T, effect_args=e_args) 19 | expect_match(x$effect[1], "2.96 [0.94 to 17.27]", fixed=TRUE) 20 | 21 | e_args$effect_tabular = effect_risk_difference 22 | x=crosstable(mtcars3, am, by=vs, effect=T, effect_args=e_args) 23 | expect_match(x$effect[1], "-1.66 [-3.79 to 0.11]", fixed=TRUE) 24 | }) 25 | 26 | 27 | # Numeric variables ------------------------------------------------------- 28 | 29 | test_that("Effects: numeric variables", { 30 | e_args = crosstable_effect_args() 31 | 32 | #e_args$effect_summarize = diff_mean_auto (default) 33 | set.seed(1234) 34 | x=crosstable(mtcars3, disp, by=vs, effect=T, effect_args=e_args) 35 | expect_match(x$effect[1], "Difference in means (bootstrap CI)", fixed=TRUE) 36 | expect_match(x$effect[1], "190.34 [119.89 to 260.78]", fixed=TRUE) 37 | 38 | e_args$effect_summarize = diff_mean_student 39 | x=crosstable(mtcars3, disp, by=vs, effect=T, effect_args=e_args) 40 | expect_match(x$effect[1], "Difference in means (t-test CI)", fixed=TRUE) 41 | expect_match(x$effect[1], "190.34 [104.14 to 276.54]", fixed=TRUE) 42 | 43 | # mtcars3 %>% map(~if(is.numeric(.x)) try(test_normality(.x, mtcars2$vs))) 44 | x=crosstable(mtcars3, hp, by=vs, effect=T) 45 | expect_match(x$effect[1], "Difference in means (Welch CI)", fixed=TRUE) 46 | expect_match(x$effect[1], "102.00 [63.49 to 140.51]", fixed=TRUE) 47 | 48 | set.seed(1234) 49 | e_args$effect_summarize = diff_mean_boot 50 | x=crosstable(mtcars3, disp, by=vs, effect=T, effect_args=e_args) 51 | expect_match(x$effect[1], "Difference in means (bootstrap CI)", fixed=TRUE) 52 | expect_match(x$effect[1], "190.34 [119.89 to 260.78]", fixed=TRUE) 53 | 54 | set.seed(1234) 55 | e_args$effect_summarize = diff_median_boot 56 | x=crosstable(mtcars3, disp, by=vs, effect=T, effect_args=e_args) 57 | expect_match(x$effect[1], "Difference in medians (bootstrap CI)", fixed=TRUE) 58 | expect_match(x$effect[1], "208.90 [89.06 to 283.31]", fixed=TRUE) 59 | }) 60 | 61 | 62 | # Survival variables ------------------------------------------------------ 63 | 64 | test_that("Effects: survival variables", { 65 | set.seed(1234) 66 | x=crosstable(mtcars3, surv, by=cyl6, effect=T) 67 | expect_match(x$effect[1], "Hazard ratio (Wald CI)", fixed=TRUE) 68 | expect_match(x$effect[1], "0.66 [0.08 to 5.41]", fixed=TRUE) 69 | 70 | crosstable(mtcars3, surv, by=am, effect=T) %>% 71 | expect_warning(class="crosstable_effect_warning") 72 | }) 73 | 74 | 75 | # Survival variables ------------------------------------------------------ 76 | 77 | test_that("Effects: missing variables", { 78 | set.seed(1234) 79 | mtcars3$x = ifelse(is.na(mtcars3$vs), "missing", paste0("cyl", mtcars3$cyl)) 80 | 81 | x = crosstable(mtcars3, x, by=vs, effect=T) %>% 82 | expect_warning2(class="crosstable_effect_warning") 83 | 84 | expect_match(attr(x, "object")$effect[1], "Odds ratio [95% Wald CI]", fixed=TRUE) 85 | expect_match(attr(x, "object")$effect[1], "missing vs cyl4", fixed=TRUE) 86 | }) 87 | 88 | 89 | # Warnings/Errors --------------------------------------------------------- 90 | 91 | 92 | test_that("Effects Warnings", { 93 | set.seed(1234) 94 | 95 | crosstable(mtcars3, cyl, by=c(am, vs), effect=T) %>% 96 | expect_warning(class="crosstable_multiby_effect_warning") 97 | 98 | crosstable(mtcars3, c(am, vs), by=cyl, effect=T) %>% 99 | expect_warning(class="crosstable_effect_2groups_warning") #3 groups 100 | crosstable(mtcars3, c(am, vs), by=dummy, effect=T) %>% 101 | expect_warning(class="crosstable_effect_2groups_warning") #1 group 102 | 103 | crosstable(mtcars3, by=vs, times=c(0,100,200,400), effect=T) %>% 104 | expect_warning("fitted probabilities numerically 0 or 1 occurred") %>% 105 | expect_warning("fitted probabilities numerically 0 or 1 occurred") %>% 106 | expect_warning("fitted probabilities numerically 0 or 1 occurred") %>% 107 | expect_warning(class="crosstable_effect_other_warning") %>% 108 | expect_warning(class="crosstable_all_na_warning") 109 | }) 110 | 111 | -------------------------------------------------------------------------------- /tests/testthat/test-effects_snap.R: -------------------------------------------------------------------------------- 1 | 2 | skip_on_cran() 3 | skip_on_ci() 4 | 5 | # skip("Too long") 6 | 7 | # Automatic snapshot tests ------------------------------------------------ 8 | # They sometimes fail on other OS than Windows due to tiny RNG differences 9 | 10 | can_be_by = function(x){ 11 | length(unique(narm(x)))==2 && !all(is.na(x)) && 12 | !is.numeric(x) && !is.Surv(x) && !is.date(x) && !inherits(x, "difftime") 13 | } 14 | # map_lgl(mtcars3, can_be_by) 15 | 16 | for(.x in names(mtcars3)){ 17 | set.seed(1234) 18 | if(can_be_by(mtcars3[[.x]])) { 19 | test_that(glue("Effect - .x='{.x}' - mean/OR (default)"), { 20 | skip_on_os(c("mac", "linux", "solaris")) 21 | local_reproducible_output(width = 1000) 22 | e_args = crosstable_effect_args() 23 | expect_snapshot({ 24 | crosstable(mtcars3, -model, by=any_of(.x), effect=T, effect_args=e_args) %>% 25 | select(.id, any_of("effect")) %>% distinct() %>% as.data.frame() 26 | }) 27 | }) 28 | 29 | test_that(glue("Effect - .x='{.x}' - mean_boot/RR"), { 30 | skip_on_os(c("mac", "linux", "solaris")) 31 | local_reproducible_output(width = 1000) 32 | e_args = crosstable_effect_args() 33 | e_args$effect_summarize = diff_mean_boot 34 | e_args$effect_tabular = effect_relative_risk 35 | expect_snapshot({ 36 | crosstable(mtcars3, -model, by=any_of(.x), effect=T, effect_args=e_args) %>% 37 | select(.id, any_of("effect")) %>% distinct() %>% as.data.frame() 38 | }) 39 | }) 40 | 41 | test_that(glue("Effect - .x='{.x}' - median/RD"), { 42 | skip_on_os(c("mac", "linux", "solaris")) 43 | local_reproducible_output(width = 1000) 44 | e_args = crosstable_effect_args() 45 | e_args$effect_summarize = diff_median_boot 46 | e_args$effect_tabular = effect_risk_difference 47 | expect_snapshot({ 48 | crosstable(mtcars3, -model, by=any_of(.x), effect=T, effect_args=e_args) %>% 49 | select(.id, any_of("effect")) %>% distinct() %>% as.data.frame() 50 | }) 51 | }) 52 | } 53 | } 54 | 55 | 56 | # test_that("Effects never fail: mean/OR (default)", { 57 | # skip_on_os(c("mac", "linux", "solaris")) 58 | # rlang::local_options(width = 100) 59 | # e_args = crosstable_effect_args() 60 | # 61 | # names(mtcars3) %>% set_names() %>% map(~{ 62 | # set.seed(1234) 63 | # if(can_be_by(mtcars3[[.x]])) { 64 | # if(!is_testing()) print(glue("Effect part 1 - by={.x}")) 65 | # expect_snapshot({ 66 | # print(glue("Effect part 1 - by={.x}")) 67 | # crosstable(mtcars3, -model, by=any_of(.x), effect=T, effect_args=e_args) %>% 68 | # select(.id, effect) %>% distinct() %>% as.data.frame() 69 | # }) 70 | # } 71 | # return(0) 72 | # }) 73 | # }) 74 | # test_that("Effects never fail: mean_boot/RR", { 75 | # skip_on_os(c("mac", "linux", "solaris")) 76 | # rlang::local_options(width = 100) 77 | # e_args = crosstable_effect_args() 78 | # e_args$effect_summarize = diff_mean_boot 79 | # e_args$effect_tabular = effect_relative_risk 80 | # 81 | # names(mtcars3) %>% set_names() %>% map(~{ 82 | # set.seed(1234) 83 | # if(can_be_by(mtcars3[[.x]])) { 84 | # if(!is_testing()) print(glue("Effect part 2 - by={.x}")) 85 | # expect_snapshot({ 86 | # print(glue("Effect part 2 - by={.x}")) 87 | # crosstable(mtcars3, -model, by=any_of(.x), effect=T, effect_args=e_args) %>% 88 | # select(.id, effect) %>% distinct() %>% as.data.frame() 89 | # }) 90 | # } 91 | # return(0) 92 | # }) 93 | # 94 | # }) 95 | # 96 | # test_that("Effects never fail: median/RD", { 97 | # skip_on_os(c("mac", "linux", "solaris")) 98 | # rlang::local_options(width = 100) 99 | # e_args = crosstable_effect_args() 100 | # e_args$effect_summarize = diff_median_boot 101 | # e_args$effect_tabular = effect_risk_difference 102 | # 103 | # map_lgl(mtcars3, can_be_by) 104 | # 105 | # names(mtcars3) %>% set_names() %>% map(~{ 106 | # if(!is_testing()) print(glue("Effect part 3 - by={.x}")) 107 | # if(can_be_by(mtcars3[[.x]])) { 108 | # expect_snapshot({ 109 | # print(glue("Effect part 3 - by={.x}")) 110 | # set.seed(1234) 111 | # crosstable(mtcars3, -model, by=any_of(.x), effect=T, effect_args=e_args) %>% 112 | # select(.id, effect) %>% distinct() %>% as.data.frame() 113 | # }) 114 | # } 115 | # return(0) 116 | # }) 117 | # }) 118 | # 119 | # 120 | -------------------------------------------------------------------------------- /tests/testthat/test-flextable.R: -------------------------------------------------------------------------------- 1 | 2 | ct0 = crosstable(mtcars3, c(mpg, am)) 3 | ct1 = crosstable(mtcars3, c(cyl, vs), by=c(am)) 4 | ct2 = crosstable(mtcars3, c(cyl, gear), by=c(am, vs)) 5 | ct3 = crosstable(mtcars3, c(disp, gear), by=c(vs, cyl3, am)) 6 | 7 | get_header_df = function(ft) ft$header$dataset 8 | 9 | 10 | test_that("header default", { 11 | expect_snapshot({ 12 | ct1 %>% as_flextable() %>% get_header_df() 13 | ct2 %>% as_flextable() %>% get_header_df() 14 | ct3 %>% as_flextable() %>% get_header_df() 15 | }) 16 | }) 17 | 18 | test_that("header by_header (monoby)", { 19 | expect_equal(ct1 %>% as_flextable(), 20 | ct1 %>% as_flextable(by_header=TRUE)) 21 | expect_equal(ct1 %>% as_flextable(by_header=NULL), 22 | ct1 %>% as_flextable(by_header=TRUE)) 23 | ct2 %>% as_flextable(by_header=FALSE) %>% expect_warning(class="crosstable_af_byheader_multi") 24 | 25 | expect_snapshot({ 26 | ct1 %>% as_flextable(by_header=NULL) %>% get_header_df() 27 | ct1 %>% as_flextable(by_header=FALSE) %>% get_header_df() 28 | }) 29 | }) 30 | 31 | test_that("generic_labels", { 32 | expect_snapshot({ 33 | crosstable(mtcars2, am, by=vs, total="both", test=TRUE, effect=TRUE) %>% 34 | rename(ID=.id, math=variable, Tot=Total, lab=label, pval=test, fx=effect) %>% 35 | as_flextable(by_header = "Engine shape", 36 | generic_labels=list(id = "ID", variable = "math", total="Tot", 37 | label = "lab", test = "pval", effect="fx")) %>% 38 | get_header_df() 39 | }) 40 | }) 41 | 42 | test_that("get_show_n_pattern", { 43 | expect_snapshot({ 44 | get_show_n_pattern() 45 | get_show_n_pattern("a") 46 | get_show_n_pattern(list(cell="a")) 47 | get_show_n_pattern(list(total="b")) 48 | get_show_n_pattern(list(cell="a", total="b")) 49 | }) 50 | get_show_n_pattern(1) %>% expect_error(class="get_show_n_pattern_class") 51 | get_show_n_pattern(c("a", "b")) %>% expect_error(class="get_show_n_pattern_class") 52 | get_show_n_pattern(list("a", "b")) %>% expect_error(class="get_show_n_pattern_names") 53 | get_show_n_pattern(list(cell=1)) %>% expect_error(class="get_show_n_pattern_length") 54 | }) 55 | 56 | 57 | test_that("header header_show_n+pattern", { 58 | expect_snapshot({ 59 | ct2 %>% 60 | as_flextable(header_show_n=TRUE, 61 | header_show_n_pattern="{.col_key}:\n{.col_val}\n(N={.n})", 62 | remove_header_keys=FALSE) %>% 63 | get_header_df() 64 | }) 65 | }) 66 | 67 | test_that("header header_show_n+remove_header_keys", { 68 | expect_snapshot({ 69 | ct2 %>% 70 | as_flextable(header_show_n=TRUE, 71 | remove_header_keys=FALSE) %>% 72 | get_header_df() 73 | }) 74 | }) 75 | 76 | 77 | 78 | # ct2 %>% as_flextable(header_show_n=1:2) %>% get_header_df() 79 | 80 | test_that("header remove_header_keys", { 81 | expect_snapshot({ 82 | ct1 %>% as_flextable(remove_header_keys=FALSE) %>% get_header_df() 83 | ct3 %>% as_flextable(remove_header_keys=FALSE) %>% get_header_df() 84 | }) 85 | }) 86 | 87 | test_that("header header_show_n", { 88 | expect_snapshot({ 89 | ct0 %>% af(header_show_n=TRUE) %>% get_header_df() 90 | ct0 %>% af(header_show_n=TRUE, by_header="foobar") %>% get_header_df() 91 | 92 | ct1 %>% af(header_show_n=TRUE) %>% get_header_df() 93 | ct1 %>% af(by_header="foobar", header_show_n=TRUE) %>% get_header_df() 94 | ct1 %>% af(by_header=FALSE, header_show_n=TRUE) %>% get_header_df() 95 | 96 | ct3 %>% af(header_show_n=TRUE) %>% get_header_df() 97 | }) 98 | }) 99 | 100 | test_that("Error empty", { 101 | crosstable(iris, 0) %>% 102 | as_flextable() %>% 103 | expect_warning(class="crosstable_empty_warning") %>% 104 | expect_error(class="crosstable_af_empty_error") 105 | }) 106 | 107 | 108 | 109 | 110 | #TODO Tests à implémenter en snapshot (2.8sec) 111 | # ct1 %>% af(header_show_n=0) %>% {.$header$dataset} 112 | # ct1 %>% af(header_show_n=0) 113 | # ct1 %>% af(header_show_n=1) 114 | # ct1 %>% af(header_show_n=2) #TODO warning? 115 | # ct1 %>% af(header_show_n=TRUE) 116 | # ct1 %>% af(header_show_n=FALSE) 117 | # 118 | # ct2 %>% af(header_show_n=0) 119 | # ct2 %>% af(header_show_n=1) 120 | # ct2 %>% af(header_show_n=2) 121 | # ct2 %>% af(header_show_n=1:2) 122 | # ct2 %>% af(header_show_n=TRUE) 123 | # ct2 %>% af(header_show_n=FALSE) 124 | # 125 | # 126 | # 127 | # ct2 %>% af(header_show_n=TRUE) 128 | # ct2 %>% af(header_show_n=TRUE, header_show_n_pattern="{.col} (N={.n})") 129 | # ct2 %>% af(header_show_n=1, header_show_n_pattern="{.col_key}:\n{.col_val}\n(N={.n})", remove_header_keys=T) 130 | # ct2 %>% af(header_show_n=TRUE, header_show_n_pattern="{.col_key} (N={.n})") 131 | 132 | 133 | 134 | # test_that("header", { 135 | # expect_snapshot({ 136 | # ct1 %>% as_flextable() %>% get_header_df() 137 | # ct2 %>% as_flextable() %>% get_header_df() 138 | # ct3 %>% as_flextable() %>% get_header_df() 139 | # }) 140 | # }) 141 | 142 | 143 | 144 | # test_that("header", { 145 | # expect_snapshot({ 146 | # ct2 %>% as_flextable() %>% {.$header$dataset} 147 | # ct2 %>% as_flextable(remove_header_keys=T) %>% {.$header$dataset} 148 | # ct2 %>% as_flextable(header_show_n=TRUE) %>% {.$header$dataset} 149 | # ct2 %>% as_flextable(header_show_n=1:2) %>% {.$header$dataset} 150 | # }) 151 | # }) 152 | 153 | -------------------------------------------------------------------------------- /tests/testthat/test-methods.R: -------------------------------------------------------------------------------- 1 | 2 | set.seed(1) 3 | ct = tibble(letter=rep(letters[1:10],3), x=rnorm(30), y=rnorm(30), z=rnorm(30)) %>% 4 | apply_labels(x="the X", y="the Y", z="the Z") %>% 5 | crosstable(by=letter) 6 | 7 | ct_c = tibble(letter=rep(letters[1:10],3), 8 | x=factor(rbinom(30, 1, .5), 0:1, c("A", "B")), 9 | y=factor(rbinom(30, 1, .5), 0:1, c("A", "B")), 10 | z=factor(rbinom(30, 1, .5), 0:1, c("A", "B"))) %>% 11 | apply_labels(x="the X", y="the Y", z="the Z") %>% 12 | crosstable(by=letter) 13 | 14 | test_that("transpose works", { 15 | expect_snapshot({ 16 | ct2 = t(ct) 17 | class(ct2) 18 | ct2 19 | af(ct2)$header$dataset 20 | }) 21 | }) 22 | 23 | test_that("transpose is interchangeable (numeric)", { 24 | ct2 = ct %>% t() %>% t() 25 | #by_table because of https://github.com/r-lib/waldo/issues/148 26 | attributes(ct2)[c("by_table", "transposed_id_labels", "inner_labels")] = NULL 27 | attributes(ct)[c("by_table")] = NULL 28 | class(ct2) = class(ct) 29 | expect_equal(ct, ct2, ignore_attr=FALSE) 30 | }) 31 | 32 | test_that("transpose is interchangeable (categorical)", { 33 | ct2 = ct_c %>% t() %>% t() 34 | #by_table because of https://github.com/r-lib/waldo/issues/148 35 | attributes(ct2)[c("by_table", "transposed_id_labels", "inner_labels")] = NULL 36 | attributes(ct_c)[c("by_table")] = NULL 37 | class(ct2) = class(ct_c) 38 | expect_equal(ct_c, ct2, ignore_attr=FALSE) 39 | }) 40 | 41 | 42 | test_that("transpose errors", { 43 | 44 | crosstable(mtcars2, c(mpg, drat), by=vs) %>% ct_compact() %>% t() %>% 45 | expect_error(class="crosstable_transpose_compact") 46 | 47 | crosstable(mtcars2, c(mpg, am), by=c(vs)) %>% t() %>% 48 | expect_error(class="crosstable_transpose_multi_var") 49 | 50 | crosstable(mtcars2, c(mpg, drat)) %>% t() %>% 51 | expect_error(class="crosstable_transpose_no_by") 52 | 53 | tibble(letter=rep(letters[1:10],3), x=rnorm(30), y=rnorm(30), z=rnorm(30)) %>% 54 | apply_labels(x="the X", y="the X", z="the Z") %>% 55 | crosstable(by=letter) %>% t() %>% 56 | expect_error(class="crosstable_transpose_labels") 57 | }) 58 | -------------------------------------------------------------------------------- /tests/testthat/test-options.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | t <- data.frame(x=c('a', 'a', 'b')) 4 | ct <- crosstable(t, cols=c('x')) 5 | gt <- as_gt(ct, generic_labels=list(value="count")) 6 | 7 | 8 | test_that("No missing options", { 9 | skip_on_ci() 10 | skip_on_cran() 11 | path = test_path("../../R") 12 | skip_if(!dir.exists(path)) 13 | 14 | ignored = c( 15 | "rec_sep", "rec_max_length", #internal, unused yet 16 | "crosstable_...", "crosstable_.local", "crosstable_reset" 17 | ) 18 | 19 | missing_options = missing_options_helper(path=path, ignore=ignored) 20 | 21 | #missing options, not handled in crosstable_options() 22 | missing_options$not_handled %>% expect_length(0) 23 | # added options, handled in crosstable_options() but never used in the code 24 | missing_options$not_used %>% expect_length(0) 25 | }) 26 | 27 | 28 | test_that("Options work", { 29 | local({ 30 | crosstable_reset_options(quiet=TRUE) 31 | x=crosstable_peek_options() 32 | expect_length(x, 0) 33 | 34 | #normal func 35 | crosstable_options(remove_zero_percent=TRUE) 36 | #legacy 37 | crosstable_options(crosstable_wrap_id=50) 38 | #duplicates 39 | expect_warning(crosstable_options(units="cm", crosstable_units="error", 40 | percent_pattern="{n}", crosstable_percent_pattern="error"), 41 | class="crosstable_dupl_option_warning") 42 | #unknown options 43 | expect_warning(crosstable_options(foo="bar", bar="foo"), 44 | class="crosstable_unknown_option_warning") 45 | 46 | x=crosstable_peek_options() 47 | expect_mapequal(x, list(crosstable_remove_zero_percent = TRUE, crosstable_wrap_id=50, 48 | crosstable_units = "cm", crosstable_percent_pattern = "{n}")) 49 | 50 | #reset 51 | expect_message(crosstable_reset_options()) 52 | expect_silent(crosstable_reset_options(quiet=TRUE)) 53 | lifecycle::expect_deprecated(crosstable_options(reset=TRUE)) 54 | expect_length(crosstable_peek_options(), 0) 55 | 56 | #default in testing env 57 | crosstable_options(crosstable_verbosity_autotesting="quiet") 58 | }) 59 | }) 60 | 61 | 62 | test_that("Renaming work", { 63 | #zero_percent was renamed to remove_zero_percent 64 | crosstable_options(zero_percent=TRUE, .local=TRUE) 65 | a=crosstable_peek_options() 66 | expect_in("crosstable_remove_zero_percent", names(a)) 67 | }) 68 | 69 | 70 | test_that("All options work", { 71 | crosstable_reset_options(quiet=TRUE) 72 | local_reproducible_output(width = 1000) 73 | set.seed(1234) 74 | # withr::deferred_clear() 75 | 76 | ct_noopt = crosstable(mtcars3, c(cyl, carb, qsec_posix, surv), by=vs, test=TRUE, effect=TRUE) %>% 77 | suppressWarnings() 78 | 79 | crosstable_options( 80 | remove_zero_percent=TRUE, 81 | only_round=TRUE, 82 | verbosity_autotesting="quiet", 83 | verbosity_duplicate_cols="quiet", 84 | total="both", 85 | percent_pattern="{n} ({p_row}, {p_col})", 86 | percent_digits=1, 87 | num_digits=1, 88 | showNA="always", 89 | label=FALSE, 90 | # funs=meansd, 91 | funs=c("Mean (SD)"=meansd), 92 | funs_arg=list(na.rm=FALSE), 93 | cor_method="kendall", 94 | unique_numeric=4, 95 | date_format="%d/%m/%Y", 96 | times=c(0,100), 97 | followup=TRUE, 98 | test_args = crosstable_test_args(plim=1), 99 | effect_args = crosstable_effect_args(conf_level=0.7), 100 | .local=TRUE 101 | ) 102 | ct_opt = crosstable(mtcars3, c(cyl, carb, qsec_posix, surv), by=vs, test=TRUE, effect=TRUE) %>% 103 | suppressWarnings() 104 | expect_snapshot({ 105 | as.data.frame(ct_noopt) 106 | as.data.frame(ct_opt) 107 | }) 108 | 109 | 110 | #as_flextable() 111 | ft_noopt = as_flextable(ct_opt) 112 | # local_options( 113 | crosstable_options( 114 | wrap_id=30, 115 | compact_padding=40, 116 | header_show_n_pattern="{.col}={.n}", 117 | keep_id=TRUE, 118 | autofit=FALSE, 119 | compact=TRUE, 120 | remove_header_keys=TRUE, 121 | show_test_name=FALSE, 122 | padding_v=0, 123 | header_show_n=TRUE, 124 | fontsize_body=8, 125 | fontsize_subheaders=9, 126 | fontsize_header=10, 127 | .local=TRUE 128 | ) 129 | ft_opt = as_flextable(ct_opt) 130 | 131 | expect_snapshot({ 132 | ft_noopt 133 | ft_opt 134 | }) 135 | 136 | # x = crosstable(mtcars3, c(cyl, carb, qsec_posix, surv), by=vs) 137 | # print(af(x)) 138 | 139 | 140 | # expect_snapshot({ 141 | # x = crosstable(mtcars3, c(cyl, carb, qsec_posix, surv), by=vs) 142 | # as.data.frame(x) 143 | # }) 144 | }) 145 | -------------------------------------------------------------------------------- /tests/testthat/test-pivot.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | set.seed(1) 5 | ct = tibble(letter=rep(letters[1:10], 3), 6 | x=sample(c("A", "B", "C"), 30, 1), 7 | y=sample(c("A", "B", "C"), 30, 1), 8 | z=sample(c("A", "B", "C"), 30, 1)) %>% 9 | mutate(across(c(x,z), ~ifelse(rbinom(n(), 1, 0.3), NA, .x))) %>% 10 | apply_labels(x="the X", y="the Y", z="the Z") %>% 11 | crosstable(-letter) 12 | 13 | 14 | 15 | 16 | test_that("pivot", { 17 | expect_snapshot({ 18 | pivot_crosstable(ct) 19 | pivot_crosstable(ct) %>% af(T) %>% {.$header$dataset} 20 | pivot_crosstable(ct) %>% af(by_header = "foobar") 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /tests/testthat/test-quick_surv.R: -------------------------------------------------------------------------------- 1 | test_that("survival POC", { 2 | 3 | # mtcars3 %>% 4 | # transmute(time=as.numeric(disp), event=as.numeric(factor(am))-1, 5 | # group=ifelse(is.na(dummy2), "A", "B")) %>% 6 | # arrange(time) %>% as.data.frame() %>% 7 | # # filter(time<150) %>% 8 | # constructive::construct() 9 | 10 | expect_snapshot({ 11 | 12 | df = data.frame( 13 | time = c(71.1, 75.7, 78.7, 79, 95.1, 108, 120.1, 120.3, 121, 140.8, 145, 146.7, 160, 14 | 160, 167.6, 167.6, 225, 258, 275.8, 275.8, 275.8, 301, 304, 318, 350, 351, 15 | 360, 360, 400, 440, 460, 472), 16 | event = rep(rep(c(1, 0), 6), c(6L, 1L, 2L, 1L, 1L, 1L, 2L, 7L, 1L, 3L, 1L, 6L)), 17 | group = rep(c("B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B"), 18 | c(9L, 1L, 1L, 1L, 2L, 3L, 1L, 1L, 7L, 2L, 4L)) 19 | ) 20 | df$time = round(df$time) 21 | df$surv = survival::Surv(df$time, df$event) 22 | fit = survival::survfit(surv~group, data=df) 23 | times = sort(unique(fit$time)) 24 | x = summary(fit, times=times, extend=TRUE) 25 | a = data.frame(strata=x$strata, time=x$time, n.risk=x$n.risk, n.event=x$n.event, surv=x$surv) 26 | 27 | a %>% 28 | dplyr::filter(strata=="group=B") %>% 29 | dplyr::filter(time==141) 30 | }) 31 | 32 | 33 | #t=140.8 34 | #on local 4.3 : 1/15 35 | #on local 4.4 : 1/15 36 | #on ubuntu-devel : 1/15 37 | #on 4.4.1 : 0/15 38 | #on release : 0/15 39 | 40 | }) 41 | 42 | 43 | # library(tidyverse) 44 | # df = data.frame( 45 | # time = c(71.1, 75.7, 78.7, 79, 95.1, 108, 120.1, 120.3, 121, 140.8, 145, 146.7, 160, 46 | # 160, 167.6, 167.6, 225, 258, 275.8, 275.8, 275.8, 301, 304, 318, 350, 351, 47 | # 360, 360, 400, 440, 460, 472), 48 | # event = rep(rep(c(1, 0), 6), c(6L, 1L, 2L, 1L, 1L, 1L, 2L, 7L, 1L, 3L, 1L, 6L)), 49 | # group = rep(c("B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B"), 50 | # c(9L, 1L, 1L, 1L, 2L, 3L, 1L, 1L, 7L, 2L, 4L)) 51 | # ) 52 | # df$time = round(df$time) 53 | # df$surv = survival::Surv(df$time, df$event) 54 | # fit = survival::survfit(surv~group, data=df) 55 | # times = sort(fit$time) 56 | # 57 | # x = summary(fit, times=times, extend=TRUE) 58 | # a = data.frame(strata=x$strata, time=x$time, n.risk=x$n.risk, n.event=x$n.event, surv=x$surv) 59 | # 60 | # a %>% 61 | # dplyr::filter(strata=="group=B") %>% 62 | # dplyr::filter(time==141) 63 | # 64 | # df %>% 65 | # dplyr::filter(time==141) 66 | # 67 | # packageVersion("survival") 68 | # R.version.string 69 | # 70 | # reprex::reprex() 71 | -------------------------------------------------------------------------------- /tests/testthat/test-tests.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | test_that("Statistical Tests", { 4 | # testthat::skip_on_cran() 5 | set.seed(0) 6 | dummy_data = tibble(x_norm=rnorm(50,0,20), x_exp=rexp(50,60), y=rnorm(50,0,20), tmt2=rep(c("A","B"), 25), tmt3=LETTERS[1:3][sample(3,50,replace=TRUE)]) 7 | 8 | ##CATEGORICAL 9 | 10 | # Fisher 11 | x=crosstable(mtcars3, cyl, by=vs, test=T) 12 | expect_equal(x$test[1], "p value: 0.0001 \n(Fisher's Exact Test for Count Data)") 13 | # Chi Square 14 | x=crosstable(iris, I(Species == "versicolor")~I(Species == "setosa"), test=T) 15 | expect_equal(x$test[1], "p value: <0.0001 \n(Pearson's Chi-squared test)") 16 | 17 | 18 | ##NUMERIC 19 | 20 | # wilcox (exact=F) 21 | x=crosstable(mtcars3, disp, by=vs, test=T) 22 | expect_equal(x$test[1], "p value: 0.0002 \n(Wilcoxon rank sum test)") 23 | # wilcox (exact=T) 24 | if(package_version(R.version) >= package_version("4.0")) { 25 | x=crosstable(dummy_data, x_exp, by=tmt2, test=T) 26 | expect_equal(x$test[1], "p value: 0.4185 \n(Wilcoxon rank sum exact test)") 27 | } else { 28 | x=crosstable(dummy_data, x_exp, by=tmt2, test=T) 29 | expect_equal(x$test[1], "p value: 0.4185 \n(Wilcoxon rank sum test)") 30 | } 31 | # t.equalvar 32 | x = crosstable(mtcars3, mpg, by=vs, test=T) 33 | expect_equal(x$test[1], "p value: <0.0001 \n(Two Sample t-test)") 34 | # t.unequalvar 35 | x=crosstable(mtcars3, hp, by=vs, test=T) 36 | expect_equal(x$test[1], "p value: <0.0001 \n(Welch Two Sample t-test)") 37 | # a.unequalvar 38 | x=crosstable(mtcars3, mpg, by=cyl, test=T) 39 | expect_equal(x$test[1], "p value: <0.0001 \n(One-way analysis of means (not assuming equal variances))") 40 | # a.equalvar 41 | x=crosstable(dummy_data, x_norm, by=tmt3, test=T) 42 | expect_equal(x$test[1], "p value: 0.1626 \n(One-way analysis of means)") 43 | # kruskal 44 | x=crosstable(mtcars3, drat, by=cyl, test=T) 45 | expect_equal(x$test[1], "p value: 0.0017 \n(Kruskal-Wallis rank sum test)") 46 | 47 | 48 | ##CORRELATION 49 | 50 | #Pearson 51 | x=crosstable(mtcars3, mpg, by=disp, cor_method="pearson", test=T) 52 | expect_equal(x$test[1], "p value: <0.0001 \n(Pearson's product-moment correlation)") 53 | #Kendall normal 54 | x=crosstable(mtcars3, mpg, by=disp, cor_method="kendall", test=T) 55 | expect_equal(x$test[1], "p value: <0.0001 \n(Kendall's rank correlation tau, normal approximation)") 56 | #Kendall exact 57 | x=crosstable(iris, Petal.Length, by=Sepal.Length, cor_method="kendall", test=T) 58 | expect_equal(x$test[1], "p value: <0.0001 \n(Kendall's rank correlation tau, exact test)") 59 | #Spearman normal 60 | x=crosstable(mtcars3, mpg, by=disp, cor_method="spearman", test=T) 61 | expect_equal(x$test[1], "p value: <0.0001 \n(Spearman's rank correlation rho, normal approximation)") 62 | #Spearman exact 63 | x=crosstable(dummy_data, x_exp, by=y, cor_method="spearman", test=T) 64 | expect_equal(x$test[1], "p value: 0.1860 \n(Spearman's rank correlation rho, exact test)") 65 | 66 | 67 | ##SURVIVAL 68 | 69 | #Logrank 70 | x=crosstable(mtcars3, surv, by=am, test=T) 71 | expect_equal(x$test[1], "p value: <0.0001 \n(Logrank test)") 72 | }) 73 | 74 | 75 | 76 | test_that("Linear contrasts test)", { 77 | skip_on_cran() 78 | skip_on_ci() 79 | my_test_args=crosstable_test_args() 80 | my_test_args$test_summarize = test_summarize_linear_contrasts 81 | x=iris %>% 82 | mutate(Petal.Width.qt = paste0("Q", ntile(Petal.Width, 5)) %>% ordered()) %>% 83 | crosstable(Petal.Length ~ Petal.Width.qt, test=TRUE, test_args = my_test_args) 84 | expect_equal(x$test[1], "p value: <0.0001 \n(Contrast test for linear trend)") 85 | expect_equal(dim(x), c(4,9)) 86 | expect_equal(sum(is.na(x)), 0) 87 | }) 88 | 89 | test_that("'Test' can be a variable name", { 90 | x=crosstable(mtcars3, test, by=vs, test=TRUE) 91 | expect_equal(x$.id[1], "test") 92 | expect_equal(dim(x), c(2,7)) 93 | }) 94 | 95 | 96 | test_that("Testing everything", { 97 | set.seed(1234) 98 | x = crosstable(mtcars3, c(disp,hp,am,surv), by=vs, margin="all", total="both", 99 | times=c(70,100,200,400), followup=TRUE, num_digits=0, percent_digits=0, 100 | test=TRUE, effect=TRUE) 101 | # expect_warning(class="crosstable_effect_warning") 102 | ft = as_flextable(x) 103 | 104 | expect_snapshot(as.data.frame(x)) 105 | expect_snapshot(ft) 106 | }) 107 | 108 | 109 | 110 | test_that("Auto-testing is bad and you should feel bad.", { 111 | rlang::local_options(crosstable_verbosity_autotesting="verbose") 112 | expect_warning(crosstable(mtcars2, disp, by=vs, funs=mean, test=T), 113 | class="crosstable_autotesting_warning") 114 | }) 115 | 116 | # snapshot_review('1-tests') 117 | -------------------------------------------------------------------------------- /tests/testthat/todo_tests.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | # library(survival) 4 | # aml$surv = Surv(aml$time, aml$status) 5 | # expss::var_lab(aml$surv) = "survival" 6 | # aml$dummy = "dummy" 7 | # aml$dummy = factor("dummy") 8 | # aml$dummy2 = c(rep("A",7), rep("B",8), rep(NA,8)) 9 | # # crosstable(aml, surv, times=c(0,15,30,150), followup=TRUE, test=T, effect=T) 10 | # crosstable(aml, surv, by=x, times=c(0,15,30,150), followup=TRUE, total=T, showNA = "always", test=T, effect=T) %>% print 11 | # crosstable(aml, surv, by=dummy, times=c(0,15,30,150), followup=TRUE, total=T, showNA = "always", test=T, effect=T) 12 | # crosstable(aml, surv, by=dummy2, times=c(0,15,30,150), followup=TRUE, total=T, showNA = "always", test=T, effect=T) 13 | 14 | #TODO faire des tests avec by=dummy partout ! 15 | # mtcars3$dummy = "dummy" 16 | 17 | 18 | 19 | # crosstable(mtcars3, mpg, cyl, by=disp) 20 | # crosstable(mtcars2, disp + hp + cyl + am ~ vs) 21 | # crosstable(mtcars2, mpg, cyl, by=vs) 22 | # crosstable(mtcars2, disp+hp+am~vs, funs_arg = list(dig=9)) 23 | # library(survival) 24 | # mtcars3=mtcars2 25 | # mtcars3$surv = Surv(mtcars3$disp, mtcars2$am=="manual") 26 | # mtcars3$dummy = "prout" 27 | # mtcars3$cyl3 = mtcars3$cyl==3 28 | # crosstable(mtcars3, disp+hp+cyl+am+Surv(disp, am=="manual")~vs, times=c(100,200,400), followup=TRUE) %>% as_flextable() 29 | # crosstable(mtcars3, disp+hp+cyl3+am+surv~vs, times=c(100,200,400), followup=TRUE, funs_arg = list(dig=9)) %>% as_flextable() 30 | # crosstable(mtcars3, disp+hp+(cyl==3)+am+surv~vs, times=c(100,200,400), followup=TRUE, funs_arg = list(dig=9), test=T, effect=T) %>% as_flextable() 31 | # crosstable(mtcars3, disp+hp+cyl+am+surv~vs, times=c(100,200,400), followup=TRUE, funs_arg = list(dig=9), test=T, effect=T) %>% as_flextable() 32 | # crosstable(mtcars3, disp+hp~vs, funs_arg = list(dig=9)) %>% as_flextable() 33 | # biostat2::cross(dummy~vs, mtcars3) 34 | 35 | 36 | # crosstable(mtcars2, c(mpg,disp), by=NULL, label=T, test=T) %>% as_flextable() 37 | # crosstable(mtcars2, c(mpg,disp), by=vs, label=T, test=T) %>% as_flextable() 38 | # crosstable(mtcars2, c(mpg,disp), by=hp, label=T, test=T) %>% as_flextable() 39 | # crosstable(mtcars3, c(mpg,surv), by=hp, label=T, test=T) %>% as_flextable(T) 40 | 41 | 42 | 43 | # crosstable(mtcars2, c(mpg,disp), by=vs, funs=c(mean,sd), funs_arg=list(dig=0, f=5), label=T, test=T, old=F) %>% as_flextable(T) 44 | # 45 | # crosstable(mtcars2, c(mpg,disp), by=NULL, funs=c(mean,sd),funs_arg=list(dig=0), label=T, test=T, old=T) %>% as_flextable() 46 | # crosstable(mtcars2, c(mpg,disp), by=vs, funs=c(mean,sd), funs_arg=list(dig=0), label=T, test=T, effect=T, total="all", old=F) %>% as_flextable(T) 47 | # crosstable(mtcars2, c(mpg,disp), by=NULL, funs=c(mean,sd),funs_arg=list(dig=0), label=T, test=T) %>% as_flextable(T) 48 | # crosstable(mtcars2, c(mpg,disp), by=vs, label=T, test=T) %>% as_flextable(T) 49 | # crosstable(mtcars2, c(mpg,disp), by=hp, label=T, test=T) %>% as_flextable(T) 50 | # crosstable(mtcars3, c(mpg,surv), by=hp, label=T, test=T) %>% as_flextable(T) 51 | # crosstable(mtcars2, c(mpg,disp), by=hp, label=T, test=T) %>% as_flextable(T) 52 | 53 | 54 | 55 | 56 | # crosstable(mtcars3, surv, times=c(100,200,400), followup=TRUE) %>% as_flextable() 57 | # crosstable(mtcars3, surv~vs, times=c(100,200,400), followup=TRUE, total="row") %>% as_flextable() 58 | # crosstable(mtcars3, surv~vs, times=c(100,200,400), followup=TRUE, total="col") %>% as_flextable() 59 | 60 | 61 | # crosstable_effect_args 62 | # crosstable(mtcars2, cyl) 63 | # biostat2::cross(cyl~., data=mtcars2, total=2) 64 | # crosstable(mtcars3, cyl, by=vs, showNA="ifany", margin=c("row","col"), total="all") %>% ctf 65 | # crosstable(mtcars3, cyl, by=vs, showNA="ifany", margin=c("col","row"), total="all") %>% ctf 66 | # biostat2::cross(cyl~vs, data=mtcars3, showNA="ifany", margin=1:2, total=1:2) 67 | 68 | # mtcars3=mtcars2 69 | # mtcars3$cyl[1:5]=NA 70 | # mtcars3$vs[5:12]=NA 71 | # crosstable(mtcars3, cyl, by=vs, showNA="no", margin="col", total="all") 72 | # crosstable(mtcars3, cyl, by=vs, showNA="ifany", margin="col", total="all") 73 | 74 | 75 | # crosstable(mtcars3, cyl, by=vs, showNA="no", margin="col", total="row") 76 | # biostat2::cross(cyl~vs, data=mtcars3, showNA="ifany", margin=2, total=1) 77 | # 78 | # crosstable(mtcars3, cyl, by=vs, showNA="no", margin="col", total="col") 79 | # biostat2::cross(cyl~vs, data=mtcars3, showNA="ifany", margin=2, total=2) 80 | # 81 | # crosstable(mtcars3, cyl, by=vs, showNA="no", margin="col", total="all") 82 | # biostat2::cross(cyl~vs, data=mtcars3, showNA="ifany", margin=2, total=TRUE) 83 | 84 | 85 | # crosstable(iris2) 86 | # crosstable(mtcars2) 87 | # 88 | # crosstable(mtcars2, mpg, disp, hp, wt, qsec, carb) 89 | # crosstable(mtcars2, disp, hp, wt, qsec) 90 | # crosstable(mtcars2, is.numeric) 91 | # crosstable(mtcars2, is.numeric, by=am) 92 | # 93 | # 94 | # 95 | # iris2$Sepal.Length %>% attributes 96 | # mtcars2$mpg %>% attributes 97 | 98 | # mtcars2 %>% (tibble::as_tibble) 99 | # crosstable(mtcars2, disp+qsec~hp) #OK 100 | # crosstable(mtcars2, disp+qsec+vs~hp) #pas OK 101 | # crosstable(iris, XX, by="Species") 102 | # crosstable(mtcars2, disp+hp+cyl+am~vs) 103 | # crosstable(mtcars2, disp+hp~vs) 104 | 105 | # library(survival) 106 | # mtcars2$surv = Surv(mtcars2$disp, mtcars2$am=="manual") 107 | # crosstable(mtcars2, disp+hp+cyl+am+Surv(disp, am=="manual")~vs, times=c(100,200,400), followup=TRUE) 108 | # crosstable(mtcars2, disp+hp+cyl+am+surv~vs, times=c(100,200,400), followup=TRUE) 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | # # cross_args2 = list(data_x=data_x, data_y=data_y, funs=funs, funs_arg=funs_arg, 118 | # # margin=margin, total=total, percent_digits=percent_digits, showNA=showNA, 119 | # # cor_method=cor_method, times=times, followup=followup, test=test, test_args=test_args, 120 | # # effect=effect, effect_args=effect_args, label=label) 121 | # # saveRDS(cross_args2, "tmp/cross_args.rds", version=2) 122 | # # rtn = do.call(cross_by, cross_args2) 123 | -------------------------------------------------------------------------------- /tests/testthat/xlsx/test_openxlsx1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/xlsx/test_openxlsx1.xlsx -------------------------------------------------------------------------------- /tests/testthat/xlsx/test_openxlsx2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/xlsx/test_openxlsx2.xlsx -------------------------------------------------------------------------------- /tests/testthat/xlsx/test_openxlsx3.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/xlsx/test_openxlsx3.xlsx -------------------------------------------------------------------------------- /tests/testthat/xlsx/test_openxlsx4.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/xlsx/test_openxlsx4.xlsx -------------------------------------------------------------------------------- /tests/testthat/xlsx/test_openxlsx5.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/xlsx/test_openxlsx5.xlsx -------------------------------------------------------------------------------- /tests/testthat/xlsx/test_openxlsx6.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/tests/testthat/xlsx/test_openxlsx6.xlsx -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/officer-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanChaltiel/crosstable/b1e301c98e5d2547d38a16bf58607d8b964392ab/vignettes/officer-example.png --------------------------------------------------------------------------------