Powerful 'SAS' Inspired Concepts for more Efficient Bigger Outputs
Overview
The main goal is to make descriptive evaluations easier to create bigger and more complex outputs in less time with less code. Introducing format containers with multilabels https://documentation.sas.com/doc/en/pgmsascdc/v_067/proc/p06ciqes4eaqo6n0zyqtz9p21nfb.htm, a more powerful summarise which is capable to output every possible combination of the provided grouping variables in one go https://documentation.sas.com/doc/en/pgmsascdc/v_067/proc/p0jvbbqkt0gs2cn1lo4zndbqs1pe.htm, tabulation functions which can create any table in different styles https://documentation.sas.com/doc/en/pgmsascdc/v_067/proc/n1ql5xnu0k3kdtn11gwa5hc7u435.htm and other more readable functions. The code is optimized to work fast even with datasets of over a million observations.
New functionality
dummy_data(): Can now generate a dummy data frame in wide format using the newwideparameter. (28.08.2026)transpose_plus(): Addedstatisticsparameter which enables the function to not only transpose sums but any availablestatistic. Can also take in a named list to output specific stats per variable like inany_table()andsummarise_plus(). (30.08.2026)frequencies(),crosstabs(): Now also capture the meta styling information. (01.09.2026)any_table(),frequencies(),crosstabs(),export_with_style(): Newoutputoption "no" prevents any styling and additionally setsprint = FALSEso that only the table and meta information are captured. (01.09.2026)combine_into_workbook(): Can now also combinefrequencies()andcrosstabs()outputs. (01.09.2026)run_script(),run_folder(),run_project(),run_project_parallel(): Single files and entire folders can be silenced (code will not be executed) by adding a "_" to the end of the file or folder name. (03.09.2026)transpose_plus(): Can now handle duplicate column names by making them unique. (10.09.2026)if.(),else_if.(),ifelse_multi(),where.(): When using the "in" operator it is now possible to capture NA values with a "." like "age in (1 2 3 4 .)". (14.09.2026)summarise_plus(): Newconvertparameter converts all class variables back to their original type after summarising. Formatted variables become character to keep their format labels, unformatted variables receive the type they had in the original data frame. (19.09.2026)transpose_plus(): In wide to long transposition, when putting variables side by side, then it is now possible to pass in multiple vectors of unequal length intopivot, if multilabel formats are applied which equalize the expression count. (20.09.2026)
Changed functionality
Show all changes in 1.3.5Hide the rest of the changes in 1.3.5
summarise_plus(): When only passingclassvariables withoutvaluesand using the defaultstatisticsthen only frequencies will be calculated instead of sums and frequencies, which would be identical. (23.08.2026)transpose_plus(): Instead of aborting when no values are passed, the function now generates a variable to output unweighted results. (28.08.2026)transpose_plus(): Received a new parametersummarisewhich summarises the data before transposing. This is the default behaviour when using formats, but was not without formats.summariseis TRUE by default. (28.08.2026)rename_multi(): Instead of throwing an error when a variable name already exists in the data frame, this renaming operation will be omitted without error instead. (10.09.2026)transpose_plus(): Now has a new default wide to long behaviour by setting variables beside each other. When setting the newstackparameter to TRUE, the old default behaviour is triggered. (12.09.2026)sub_string(): If a numeric variable is passed, then now the function doesn't throw an error anymore, but rather takes the substring of the numeric values. (14.09.2026)compute.(),if.(),else_if.(),else.(): On a type mismatch the type of the newly calculated value now always wins instead of converting everything to character and emitting a warning. (17.09.2026)summarise_plus(): Class variables are now converted to either character or numeric by default instead of being returned as factors. Set the newconvertparameter to FALSE to get back the past behaviour. (19.09.2026)
Fixed
combine_into_workbook(): Fixed table of contents example not working as intended. (21.08.2026)crosstabs(): If a vector of variables is provided forcolumnsthen now the first variable will be picked instead of the second one. (26.08.2026)else_if(),else.(): When assigning to multiple variables in a do-over-loop situation the functions would only consider the first assignment. This is fixed now. (26.08.2026)transpose_plus(): The function had a serious flaw. When transposing multiple variables at once the results were always picked from the all nested results even though they have to be picked from their respective combination. This is fixed now. (28.08.2026)transpose_plus(): If an invalid format is passed, this now throws a warning instead of removing all formats silently. (30.08.2026)remove_stat_extension(): When a vector was passed only the last element was considered. Now all passed stat extensions are removed. (30.08.2026)interval_format(): Include boundaries weren't detected correctly, this is fixed now. (31.08.2026)summarise_plus(): Doesn't error anymore if theclassvariable is identical to thevaluesvariable. (31.08.2026)any_table(): Tabulating pre summarised data ran into an error if thevaluevariables had no statistic extensions. This is fixed now. (31.08.2026)any_table(): Column header columns could be sorted in the wrong order if a statistic extension was also part of a label in some way. The sorting is now adjusted that only the real extensions are detected. (31.08.2026)recode_multi(): When recoding a variable into numeric values then the desired numeric values are output instead of the factor values. (01.09.2026)recode_multi(): When a variable is invalid then the function aborts with an error message instead of just crashing. (01.09.2026)if.(),else_if.(),else.(),ifelse_multi(),where.(): When a variable inside a condition or an assignment is invalid then the function aborts with an error message instead of just crashing. (01.09.2026)import_data(),import_multi(): Should now detect csv and txt encoding correctly. (03.09.2026)export_with_style(): First column isn't set up as row header column anymore it is now treated as part of the table. (03.09.2026)compute.(): If the same variable name was used more than once for an assignment, the function now returns the last result for this variable instead of the first. (05.09.2026)concat(): Now throws an error if a variable name is not part of the data frame. (10.09.2026)concat(): Now also works withincompute.(). (10.09.2026)sub_string(): Now also works withincompute.(). (12.09.2026)transpose_plus(): When using multiple statistics the new variable names are now named as intended. (12.09.2026)ifelse_multi(): Now also works withincompute.(). (14.09.2026)discrete_format(): When the keyword "other" is used while the original values are characters, they will now stay as provided instead of being translated into all lower case. (14.09.2026)summarise_plus(): Numeric variables stored as character no longer lose their original characters (e.g. leading zeros) when a format is applied to another variable. They now stay as character variables. (19.09.2026)dummy_data(): Fixed a rare edge case were fewer observations were generated than intended. (20.09.2026)multi_join(): When joining more than two data frames with different join methods, then now the observations which are added by a widening join (e.g. right, full, outer) are kept by the following joins instead of being dropped. (20.09.2026)
Optimization
apply_formats(): Removed unnecessary calculation. Additionally optimzed checking for NA values for discrete formats. (29.08.2026)summarise_plus(): Withnesting = "all" or "singlea list of logical vectors containing non NA observations is now computed once before generating all combinations, which allows to remove the individual data frame scanning per combination. (29.08.2026)any_table(),frequencies(),crosstabs(),export_with_style(): Moved column width and row height adjustments before the background coloring to make it run only over the table span instead of the whole sheet. (30.08.2026)
Additionally
any_table(),transpose_plus(): The deduplicated variable names are now cleaned up so that they only receive one duplicate suffix. (12.09.2026)multi_join(): Now displays duplicated variable combinations in the error message. (20.09.2026)
From NEWS.md in the release
Install
Health
- OK13 OK2026-08-05
- NOTE12 OK, 1 NOTE2026-08-01
- OK13 OK2026-07-03
- ERROR11 OK, 1 ERROR2026-04-25
- OK14 OK2026-04-11
Show 4 earlier changesHide 4 earlier changes
- ERROR13 OK, 1 ERROR2026-04-09
- OK14 OK2026-03-25
- ERROR13 OK, 1 ERROR2026-03-21
- OK14 OK2026-03-10
Documentation
The repository also keeps web-only articles.
- Help pages
- 70 (6 internal)includes a package overview page
- Examples that run
- 100%64 run in a plain check
- Exported functions with examples
- 93%
- Documented parameters
- 99%
- Return-value docs
- 100%
- Help pages citing references
- 0%
Downloads
Repository
- PRs merged (all time)
- 75%
- Median days to close, 50 most recently updated closed issues
- 1
- Median days to close, 50 most recently updated closed PRs
- 0
Stars over time
Forks over time
Releases over time
Issues over time
PRs over time
Commits over time
6 development-tooling and community-health practices detected across 4 families in the upstream repository
Checks run against github.com/s3rdia/qol on 2026-10-21.
GitHub Pages site last deployed 2026-10-21
pkgdown site last built 2026-10-21
Dependencies
Installing qol adds 8 packages (7 with compiled code, 22 MB of source tarballs). Heaviest: stringi 11 MB, data.table 5.7 MB, Rcpp 1.8 MB.
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 1.3.5Latest
- 1.3.42026-07-16 · diff ↗ ·
removed 1 export
get_integer_lengthadded 6 exports
check_required_package, create_table_of_contents, run_folder, run_project, run_project_parallel, run_script - 1.3.3
- 1.3.22026-06-16 · diff ↗ ·
removed 5 exports
get_stat_labels, get_variable_labels, retain_sum, set_stat_labels, set_variable_labelsadded 4 exports
code_statistics, get_labels, retain_stat, set_labels - 1.3.12026-05-16 · diff ↗ ·
removed 2 exports
compute, recodeadded 3 exports
compute., recode., set_no_color - RR 4.6.0 released · 2026-04-24
- 1.3.02026-04-18 · diff ↗ ·
added 29 exports
compute, convert_square_brackets, do_if, else_do, end_all_do, end_do, get_message_stack, get_threads, hex_to_256, hex_to_ansi, load_file, load_file_multi, print_closing, print_headline, print_message, print_stack_as_messages, print_start_message, print_step, qol_chat, report_test_results, round_multi, row_calculation, save_file, save_file_multi, set_no_print, set_threads, set_up_custom_message, test_package, test_single_file - 1.2.2
- 1.2.12026-02-11 · diff ↗ ·
added 14 exports
apply_macro, concat, expand_formats, export_multi, free_memory, get_duplicate_var_count, get_duplicate_var_names, get_print_miss, import_multi, macro, remove_blanks, set_print_miss, sub_string, where. - 1.2.02026-01-13 · diff ↗ ·
removed 3 exports
is_numeric, split_by_condition, split_by_varadded 42 exports
add_variable_range, check_weight, close_file, content_report, convert_factor, dots_to_char, export_data, first_row_as_names, get_footnotes, get_integer_length, get_monitor, get_na.rm, get_origin_as_char, get_output, get_print, get_stat_labels, get_style_options, get_titles, get_variable_labels, import_data, part_of_df, qol_news, remove_doubled_values, rename_multi, reset_qol_options, reset_style_options, resolve_intersection, retain_variables, set, set_footnotes and 12 more - 1.1.1
- 1.1.02025-11-20 · diff ↗ ·
added 7 exports
build_master, build_rstheme, combine_into_workbook, mark_case, replace_except, retain_sum, retain_value - 1.0.22025-10-14 · diff ↗
- 1.0.12025-10-10
- RR 4.5.0 released · 2025-04-11
Package metadata
- First published
- 2025-10-10
- Total releases
- 13 / 1 yrs
- License
- MIT + file LICENSE OSI
- Minimum R
- ≥ 4.1.0
- Download size
- 833 KB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("qol")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-24, which the citation names so these numbers can be found later. More on citing and the projects behind them.