% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/any_table.R
\name{any_table}
\alias{any_table}
\title{Compute Any Possible Table}
\usage{
any_table(
  data_frame,
  rows,
  columns = "",
  values,
  statistics = NULL,
  pct_group = c(),
  pct_value = list(),
  pct_block = c(),
  compute = list(),
  formats = list(),
  by = c(),
  weight = NULL,
  order_by = "stats",
  titles = .qol_options[["titles"]],
  footnotes = .qol_options[["footnotes"]],
  var_labels = .qol_options[["var_labels"]],
  stat_labels = .qol_options[["stat_labels"]],
  box = "",
  workbook = NULL,
  style = .qol_options[["excel_style"]],
  output = .qol_options[["output"]],
  na.rm = .qol_options[["na.rm"]],
  print_miss = .qol_options[["print_miss"]],
  print = .qol_options[["print"]],
  monitor = .qol_options[["monitor"]]
)
}
\arguments{
\item{data_frame}{A data frame in which are the variables to tabulate.}

\item{rows}{A vector that provides single variables or variable combinations that
should appear in the table rows. To nest variables use the form:
"var1 + var2 + var3 + ...".}

\item{columns}{A vector that provides single variables or variable combinations that
should appear in the table rows. To nest variables use the form:
"var1 + var2 + var3 + ...".}

\item{values}{A vector containing all variables that should be summarised.}

\item{statistics}{Available functions:
\itemize{
\item "sum"       -> Weighted and unweighted sum
\item "sum_wgt"   -> Sum of all weights
\item "freq"      -> Unweighted frequency
\item "freq_g0"   -> Unweighted frequency of all values greater than zero
\item "pct_group" -> Weighted and unweighted percentages within the respective group
\item "pct_value" -> Weighted and unweighted percentages between value variables or of a variable expression
\item "pct_total" -> Weighted and unweighted percentages compared to the grand total
\item "mean"      -> Weighted and unweighted mean
\item "median"    -> Weighted and unweighted median
\item "mode"      -> Weighted and unweighted mode
\item "min"       -> Minimum
\item "max"       -> Maximum
\item "sd"        -> Weighted and unweighted standard deviation
\item "variance"  -> Weighted and unweighted standard variance
\item "first"     -> First value
\item "last"      -> Last value
\item "pn"        -> Weighted and unweighted percentiles (any p1, p2, p3, ... possible)
Uses the SAS default way of calculating percentiles, which is Type 2 described in \code{\link[=quantile]{quantile()}}.
\item "missing"   -> Missings generated by the value variables
}}

\item{pct_group}{This option is used to determine which variable of the row and column
variables should add up to 100 \%. Multiple variables can be specified in a vector to
generate multiple group percentages. You can also use the keywords "row_pct" or "col_pct"
to calculate total percentages for rows and columns regardless of the respective other dimension.}

\item{pct_value}{You can pass a list here, which contains the information for a new
variable name and between which of the value variables percentages should be computed.}

\item{pct_block}{Can be "rows" or "columns". Calculates percentages for the last
group of variables inside the individual row or column combinations.}

\item{compute}{A list in which individual calculations are handled. For the writing style
see the \code{\link[=compute.]{compute.()}} function.}

\item{formats}{A list in which is specified which formats should be applied to which variables.}

\item{by}{Compute tables stratified by the expressions of the provided variables.}

\item{weight}{Put in a weight variable to compute weighted results.}

\item{order_by}{Determine how the columns will be ordered. "values" orders the results by the
order you provide the variables in values. "stats" orders them by the order under statistics.
"values_stats" is a combination of both. "columns" keeps the order as given in columns
and "interleaved" alternates the stats.}

\item{titles}{Specify one or more table titles.}

\item{footnotes}{Specify one or more table footnotes.}

\item{var_labels}{A list in which is specified which label should be printed for
which variable instead of the variable name.}

\item{stat_labels}{A list in which is specified which label should be printed for
which statistic instead of the statistic name.}

\item{box}{Provide a text for the upper left box of the table.}

\item{workbook}{Insert a previously created workbook to expand the sheets instead of
creating a new file.}

\item{style}{A list of options can be passed to control the appearance of 'Excel' outputs.
Styles can be created with \code{\link[=excel_output_style]{excel_output_style()}}.}

\item{output}{The following output formats are available: excel and excel_nostyle.}

\item{na.rm}{FALSE by default. If TRUE removes all NA values from the variables.}

\item{print_miss}{FALSE by default. If TRUE outputs all possible categories of the
grouping variables based on the provided formats, even if there are no observations
for a combination.}

\item{print}{TRUE by default. If TRUE prints the output, if FALSE doesn't print anything. Can be used
if one only wants to catch the output data frame and workbook with meta information.}

\item{monitor}{FALSE by default. If TRUE, outputs two charts to visualize the functions time consumption.}
}
\value{
Returns a list with the data table containing the results for the table, the formatted
'Excel' workbook and the meta information needed for styling the final table.
}
\description{
\code{\link[=any_table]{any_table()}} produces any possible descriptive table in 'Excel' format. Any number
of variables can be nested and crossed. The output is an individually styled
'Excel' table, which also receives named ranges, making it easier to read the data back in.
}
\details{
\code{\link[=any_table]{any_table()}} is based on the 'SAS' procedure Proc Tabulate, which provides
efficient and readable ways to perform complex tabulations.

With this function you can combine any number of variables in any possible way, all
at once. You just define which variables or variable combinations should end up in
the table rows and columns with a simple syntax. Listing variables in a vector like
c("var1", "var2", "var3",...) means to put variables below (in case of the
row variables) or besides (in case of the column variables) each other. Nesting variables
is as easy as putting a plus sign between them, e.g. c("var1 + var2", "var2" + "var3" + "var4", etc.).
And of course you can combine both versions.

The real highlight is, that this function not only creates all the desired variable
combinations and exports them to an 'Excel' file, it prints a fully custom styled
table to a workbook. Setting up a custom, reusable style is as easy as setting up
options like: provide a color for the table header, set the font size for the row header,
should borders be drawn for the table cells yes/no, and so on. Merging doubled header texts,
happens automatically.

With this function you basically can fully concentrate on designing a table, instead of
thinking hard about how to calculate where to put a border or to even manually prepare
a designed workbook.
}
\examples{
# NOTE: Some of the examples use the parameter 'output = "excel_nostyle"' to
#       make them run faster so that more examples can be provided. Take out
#       the parameter to get the fully styled excel table.
#       The global option for printing the output is also set to FALSE for
#       the same reason. When running the examples manually, don't run this
#       option here.
set_print(FALSE)
set_style_options(background_color = "")

# Example data frame
my_data <- dummy_data(1000)
my_data[["person"]] <- 1

# Formats
age. <- discrete_format(
    "Total"          = 0:100,
    "under 18"       = 0:17,
    "18 to under 25" = 18:24,
    "25 to under 55" = 25:54,
    "55 to under 65" = 55:64,
    "65 and older"   = 65:100)

sex. <- discrete_format(
    "Total"  = 1:2,
    "Male"   = 1,
    "Female" = 2)

# NOTE: "!" in front of an expression makes the expression available for
#       calculations but prevents it from beeing printed out.
education. <- discrete_format(
    "!Total"           = c("low", "middle", "high"),
    "low education"    = "low",
    "middle education" = "middle",
    "high education"   = "high")

state. <- discrete_format(
    "Germany"                       = 1:16,
    "Schleswig-Holstein"            = 1,
    "Hamburg"                       = 2,
    "Lower Saxony"                  = 3,
    "Bremen"                        = 4,
    "North Rhine-Westphalia"        = 5,
    "Hesse"                         = 6,
    "Rhineland-Palatinate"          = 7,
    "Baden-Württemberg"             = 8,
    "Bavaria"                       = 9,
    "Saarland"                      = 10,
    "West"                          = 1:10,
    "Berlin"                        = 11,
    "Brandenburg"                   = 12,
    "Mecklenburg-Western Pomerania" = 13,
    "Saxony"                        = 14,
    "Saxony-Anhalt"                 = 15,
    "Thuringia"                     = 16,
    "East"                          = 11:16)

# Define style
set_style_options(column_widths = c(2, 15, 15, 15, 9))

# Define titles and footnotes. If you want to add hyperlinks you can do so by
# adding "link:" followed by the hyperlink to the main text. Linking to another
# cell works with "cell:". To link to a file use "file:" an pass the full file
# path afterwards.
set_titles("This is title number 1",
           "This is title number 2 link: https://cran.r-project.org/",
           "This is title number 3 cell: W22",
           "This is title number 4 file: C:/MyFolder/MyFile.txt")

set_footnotes("This is footnote number 1",
              "This is footnote number 2 file: C:/MyFolder/MyFile.txt",
              "This is footnote number 3 cell: W22",
              "This is footnote number 4 link: https://cran.r-project.org/")

# Output complex tables with different percentages
my_data |> any_table(rows      = c("sex + age", "sex", "age"),
                     columns   = c("year", "education + year"),
                     values    = weight,
                     pct_group = c("row_pct", "col_pct"),
                     formats   = list(sex = sex., age = age.,
                                      education = education.),
                     na.rm     = TRUE)

# If you want to get a clearer vision of what the result table looks like, in terms
# of the row and column categories, you can write the code like this, to make out
# the variable crossings and see the order.
# my_data |> any_table(columns   = c(            "year", "education + year"),
#                      rows      = c("sex + age",
#                                    "sex",
#                                    "age"),
#                      values    = weight,
#                      pct_group = c("sex", "age"),
#                      formats   = list(sex = sex., age = age.,
#                                       education = education.),
#                      output    = "excel_nostyle",
#                      na.rm     = TRUE)

# Percentages based on value variables instead of categories
my_data |> any_table(rows       = c("age + year"),
                     columns    = "sex",
                     values     = c(probability, person),
                     statistics = c("pct_value", "sum", "freq"),
                     pct_value  = list(rate = "probability / person"),
                     weight     = weight,
                     formats    = list(sex = sex., age = age.),
                     output    = "excel_nostyle",
                     na.rm      = TRUE)

# Percentages based on a formatted variable expression
my_data |> any_table(rows       = c("age + year"),
                     columns    = "sex",
                     values     = c(probability, person),
                     pct_value  = list(sex = "Total", age = "Total"),
                     weight     = weight,
                     formats    = list(sex = sex., age = age.),
                     output    = "excel_nostyle",
                     na.rm      = TRUE)

# Percentages based on variable combination blocks
# NOTE: age + (year, education) becomes "age + year" and "age + education"
#       and will be sorted together. Also works in columns. You can also
#       do something like this: age + (year, sex + education, education).
my_data |> any_table(rows       = c("sex + (age, education)"),
                     columns    = "year",
                     values     = weight,
                     pct_block  = c("rows", "columns"),
                     formats    = list(sex = sex., age = age.,
                                       education = education.),
                     output     = "excel_nostyle",
                     na.rm      = TRUE)

# Individual calculations
my_data |> any_table(rows       = c("age + year"),
                     columns    = "sex",
                     values     = "probability",
                     statistics = c("sum", "sum_wgt"),
                     compute    = list(percent    = probability_sum * 100 / sum_wgt,
                                       pct_square = percent ^ 2),
                     weight     = weight,
                     formats    = list(sex = sex., age = age.),
                     output    = "excel_nostyle",
                     na.rm      = TRUE)

# Customize the visual appearance by adding variable and statistic labels. Both
# can also be set as a global option, if labels should be reused over multiple
# tables.
# Note: You don't have to describe every element. Sometimes a table can be more
# readable with less text. To completely remove a variable label just put in an
# empty text "" as label.#'
set_titles("This is title number 1",
           "This is title number 2",
           "This is title number 3")

set_footnotes("This is footnote number 1",
              "This is footnote number 2",
              "This is footnote number 3")

my_data |> any_table(rows        = c("age + year"),
                     columns     = "sex",
                     values      = weight,
                     statistics  = c("sum", "pct_group"),
                     order_by    = "interleaved",
                     formats     = list(sex = sex., age = age.),
                     var_labels  = list(age = "Age categories",
                                        sex = "", weight = ""),
                     stat_labels = list(pct = "\%"),
                     output      = "excel_nostyle",
                     na.rm       = TRUE)

# Individual styling can also be passed directly
my_style <- excel_output_style(header_back_color = "0077B6",
                               font              = "Times New Roman")

# my_data |> any_table(rows       = c("age + year"),
#                      columns    = "sex",
#                      values     = c(probability, person),
#                      statistics = c("pct_value", "sum", "freq"),
#                      pct_value  = list(rate = "probability / person"),
#                      weight     = weight,
#                      formats    = list(sex = sex., age = age.),
#                      style      = my_style,
#                      na.rm      = TRUE)

# Select specific statistics for specific variables
my_data |> any_table(rows       = "sex",
                     columns    = "year",
                     statistics = list("sum"       = c(weight, income),
                                       "pct_group" = balance),
                     formats    = list(sex = sex.),
                     output     = "excel_nostyle",
                     na.rm      = TRUE)

# Pass on workbook to create more sheets in the same file
my_style <- my_style |> modify_output_style(sheet_name = "age_sex")

result_list <- my_data |>
           any_table(rows       = "age",
                     columns    = "sex",
                     values     = weight,
                     statistics = "sum",
                     formats    = list(sex = sex., age = age.),
                     style      = my_style,
                     output     = "excel_nostyle",
                     na.rm      = TRUE,
                     print      = FALSE)

my_style <- my_style |> modify_output_style(sheet_name = "edu_year")

my_data |> any_table(workbook   = result_list[["workbook"]],
                     rows       = "education",
                     columns    = "year",
                     values     = weight,
                     statistics = "pct_group",
                     formats    = list(education = education.),
                     style      = my_style,
                     output     = "excel_nostyle",
                     na.rm      = TRUE)

# In case you have a good amount of tables, you want to combine in a single workbook,
# you can also catch the outputs and combine them afterwards in one go.
# NOTE: This section is commented out to just show the principle. Otherwise the
#       example code would run for too long.
# set_style_options(sheet_name = "sheet1")
# tab1 <- my_data |> any_table(..., print = FALSE, output = "excel_nostyle")
#
# set_style_options(sheet_name = "sheet2")
# tab2 <- my_data |> any_table(..., print = FALSE, output = "excel_nostyle")
#
# set_style_options(sheet_name = "sheet3")
# tab3 <- my_data |> any_table(..., print = FALSE, output = "excel_nostyle")
#
# ...
#
# Every of the above tabs is a list, which contains the data table, an unstyled
# workbook and the meta information needed for the individual styling. These tabs
# can be input into the following function, which reads the meta information, styles
# each table individually and combines them as separate sheets into a single workbook.
# combine_into_workbook(tab1, tab2, tab3 file = "C:/My_folder/My_workbook.xlsx")

# The result list from above also carries the transformed data frame if
# needed for further usage
any_table_df <- result_list[["table"]]

# Output multiple complex tables by expressions of another variable.
# If you specify the sheet name as "by" in the output style, the sheet
# names are named by the variable expressions of the by-variable. Otherwise
# the given sheet named gets a running number.
my_style <- my_style |> modify_output_style(sheet_name = "by")

my_data |> any_table(rows       = c("sex", "age"),
                     columns    = "education",
                     values     = weight,
                     by         = state,
                     statistics = c("sum", "pct_group"),
                     pct_group  = "education",
                     formats    = list(sex = sex., age = age., state = state.,
                                       education = education.),
                     output     = "excel_nostyle",
                     na.rm      = TRUE)

# To save a table as xlsx file you have to set the path and filename in the
# style element
# Example files paths
table_file <- tempfile(fileext = ".xlsx")

# Note: Normally you would directly input the path ("C:/MyPath/") and name ("MyFile.xlsx").
set_style_options(save_path  = dirname(table_file),
                  file       = basename(table_file),
                  sheet_name = "MyTable")

my_data |> any_table(rows    = "sex",
                     columns = "year",
                     values  = weight,
                     formats = list(sex = sex.))

# Manual cleanup for example
unlink(table_file)

# Global options are permanently active until the current R session is closed.
# There are also functions to reset the values manually.
reset_style_options()
reset_qol_options()
close_file()

set_print(TRUE)
set_style_options(background_color = "FFFFFF")

}
\seealso{
Creating a custom table style: \code{\link[=excel_output_style]{excel_output_style()}}, \code{\link[=modify_output_style]{modify_output_style()}},
\code{\link[=number_format_style]{number_format_style()}}, \code{\link[=modify_number_formats]{modify_number_formats()}}.

Global style options: \code{\link[=set_style_options]{set_style_options()}}, \code{\link[=set_labels]{set_labels()}}.

Other global options: \code{\link[=set_titles]{set_titles()}}, \code{\link[=set_footnotes]{set_footnotes()}}, \code{\link[=set_print]{set_print()}}, \code{\link[=set_monitor]{set_monitor()}},
\code{\link[=set_na.rm]{set_na.rm()}}, \code{\link[=set_print]{set_print()}}, \code{\link[=set_print_miss]{set_print_miss()}}, \code{\link[=set_output]{set_output()}}.

Combine Excel workbooks: \code{\link[=combine_into_workbook]{combine_into_workbook()}}.

Creating formats: \code{\link[=discrete_format]{discrete_format()}} and \code{\link[=interval_format]{interval_format()}}.

Functions that can handle formats and styles: \code{\link[=frequencies]{frequencies()}}, \code{\link[=crosstabs]{crosstabs()}}.

Additional functions that can handle styles: \code{\link[=export_with_style]{export_with_style()}}

Additional functions that can handle formats: \code{\link[=summarise_plus]{summarise_plus()}}, \code{\link[=recode.]{recode.()}},
\code{\link[=recode_multi]{recode_multi()}}, \code{\link[=transpose_plus]{transpose_plus()}}, \code{\link[=sort_plus]{sort_plus()}}
}
