Skip to content

Commit

Permalink
Rework backend for more flexibility and add new options
Browse files Browse the repository at this point in the history
Main new features:
- There is an `extralines` argument that can accept vectors with pairs, where the pair defines a multicolumn value (`["Label", "two columns" => 2:3, 1.5 => 4:5]`), it can also accept a `DataRow` object that allows for more control.
- New `keep` `drop` and `order` arguments allow exact names, regex to search within names, integers to select specific values, and ranges (`1:4`) to select groups, and they can be mixed (`[1:2, :end, r"Width"]`)
- `labels` now applies to individual parts of an interaction or categorical coefficient name (hopefully reducing the number of labels required)
- The interaction symbol now depends on the table type, so in Latex, the interactions will have ` \$\\times\$ `
  - Using a Latex table will also automatically escape parts of coefficient names (if no other labels are provided)
- A confidence interval is now an option for a below statistic (`below_statistic=ConfInt`)
- Several defaults are different to try and provide more relevant information (see changes do defaults section)
- Fixed effect values now have a suffix (defaults to `" Fixed Effects"`) so that labeling can be simpler. Disable by setting `print_fe_suffix=false`
- It is now possible to print the coefficient value and "under statistic" on the same line (`stat_below=false`)
- It is possible to define custom regression statistics that are calculated based on the regressions provided
- It is possible to change the order of the major blocks in a regression table
- Using RegressionTables for descriptive statistics is now easier. Describe a DataFrame (`df_described=describe(df)`) and provide that to a RegressionTable (`tab = RegressionTable(names(df_described), Matrix(df_described))`), there are also options to render the table as a `LatexTable` or `HtmlTable`. Write this to a file using `write(file_name, tab)`
- It is possible to overwrite almost any setting. For example, to make T-Statistics the default in all tables, run `RegressionTables.default_below_statistic(render::AbstractRenderType)=TStat`
- Option to show clustering (`print_clusters=true`).
  - Can also be the size of the clusters by running `Base.repr(render::AbstractRenderType, x::RegressionTables.ClusterValue; args...) = repr(render, value(x); args...)`
- Several new regression statistics are now available, the full list is: `[Nobs, R2, PseudoR2, R2CoxSnell, R2Nagelkerke, R2Deviance, AdjR2, AdjPseudoR2, AdjR2Deviance, DOF, LogLikelihood, AIC, AICC, BIC, FStat, FStatPValue, FStatIV, FStatIVPValue, R2Within]`
- Use `LatexTableStar` to create a table that expands the entire text width
  • Loading branch information
junder873 authored Dec 4, 2023
2 parents 34c5256 + 9c028a8 commit c80aea9
Show file tree
Hide file tree
Showing 60 changed files with 6,389 additions and 1,341 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CompatHelper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ jobs:
CompatHelper.main()
shell: julia --color=yes {0}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

3 changes: 2 additions & 1 deletion .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ jobs:
steps:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
ssh: ${{ secrets.DOCUMENTER_KEY }}
22 changes: 20 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.8' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
- '1.9' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
- '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia.
- 'nightly'
os:
Expand Down Expand Up @@ -43,4 +43,22 @@ jobs:
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
with:
file: lcov.info
file: lcov.info
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: '1'
arch: x64
- run: |
julia --project=docs -e '
using Pkg
Pkg.develop(PackageSpec(path=pwd()))
Pkg.instantiate()'
- run: julia --project=docs docs/make.jl
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Manifest.toml
Manifest.toml
docs/build/
docs/site/
29 changes: 22 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
name = "RegressionTables"
uuid = "d519eb52-b820-54da-95a6-98e1306fdade"
authors = ["Johannes Boehm <[email protected]>"]
version = "0.5.10"
version = "0.6.0"

[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FixedEffectModels = "9d5cd8c9-2029-5cab-9928-427838db53e3"
Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0"
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsAPI = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"

[weakdeps]
FixedEffectModels = "9d5cd8c9-2029-5cab-9928-427838db53e3"
GLFixedEffectModels = "bafb0ae5-e5f5-5100-81b6-6a55d777c812"
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
MixedModels = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316"

[extensions]
RegressionTablesFixedEffectModelsExt = "FixedEffectModels"
RegressionTablesGLFixedEffectModelsExt = "GLFixedEffectModels"
RegressionTablesGLMExt = "GLM"
RegressionTablesMixedModelsExt = "MixedModels"

[compat]
Compat = "2, 3, 4"
Aqua = "0.8"
Distributions = "0.21, 0.23, 0.24, 0.25"
FixedEffectModels = "1.9"
Formatting = "0.4"
GLFixedEffectModels = "0.5"
GLM = "1.3"
MixedModels = "4"
Statistics = "1"
StatsAPI = "1.6"
StatsBase = "0.32, 0.33, 0.34"
StatsModels = "0.7"
julia = "1.8"
StatsModels = "0.7.3"
julia = "1.9"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
339 changes: 216 additions & 123 deletions README.md

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FixedEffectModels = "9d5cd8c9-2029-5cab-9928-427838db53e3"
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
MixedModels = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
RegressionTables = "d519eb52-b820-54da-95a6-98e1306fdade"
30 changes: 30 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using RegressionTables, RDatasets, GLM, FixedEffectModels
using Documenter

DocMeta.setdocmeta!(
RegressionTables,
:DocTestSetup,
quote
using RegressionTables
end;
recursive=true
)

Documenter.makedocs(
modules = [RegressionTables],
sitename = "RegressionTables.jl",
pages = [
"Introduction" => "index.md",
"Regression Statistics" => "regression_statistics.md",
"Examples" => "examples.md",
"Keep Drop and Order Arguments" => "keep_drop_order.md",
"API" => "api.md",
"Customization and Defaults" => "customization.md",
"Function and Type Reference" => "function_reference.md"
]
)

deploydocs(
repo = "github.com/jmboehm/RegressionTables.jl.git",
target = "build",
)
86 changes: 86 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

# API of Underlying Functions

```@contents
Pages=["api.md"]
Depth = 3
```

## DataRow

```@docs
RegressionTables.DataRow
```

## RegressionTable

```@docs
RegressionTables.RegressionTable
```

## Render Types

```@docs
RegressionTables.AbstractRenderType
```

### Ascii

```@docs
RegressionTables.AbstractAscii
RegressionTables.AsciiTable
```

### Latex

```@docs
RegressionTables.AbstractLatex
RegressionTables.LatexTable
RegressionTables.LatexTableStar
```

### HTML

```@docs
RegressionTables.AbstractHtml
RegressionTables.HtmlTable
```

## Coefficient Naming

```@docs
RegressionTables.AbstractCoefName
RegressionTables.get_coefname
```

```@autodocs
Modules = [RegressionTables]
Filter = t -> typeof(t) === DataType && t <: RegressionTables.AbstractCoefName && t != RegressionTables.AbstractCoefName
```

## Utility Functions

```@docs
RegressionTables.calc_widths
RegressionTables.update_widths!
RegressionTables.value_pos
RegressionTables.combine_other_statistics
RegressionTables.combine_statistics
RegressionTables.build_nm_list
RegressionTables.reorder_nms_list
RegressionTables.drop_names!
RegressionTables.add_blank
RegressionTables.missing_vars
RegressionTables.other_stats
RegressionTables.add_element!
```

## How Types are Displayed

This section describes how different types are displayed. Throughout this package, `repr(T(), x)` where `T` is a concrete type of [`AbstractRenderType`](@ref) is used to convert something to a string. This allows two things.
1. Since it is easy to create new `AbstractRenderType`s, it is possible to create customized displays for almost anyway situation
2. Since most things in this package are types, each can be customized

```@docs
Base.repr
```
113 changes: 113 additions & 0 deletions docs/src/customization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@

# Customization of Defaults

```@index
Pages=["customization.md"]
```

## Principles

Within most publications, the tables look similar. This package tries to provide easy access to almost any setting so you can "set and forget" while producing tables that you need. For example, suppose you are using Latex and want to use the `tabular*` environment instead of the default `tabular`. Thanks to the Julia type system, this is possible, simply run
```julia
RegressionTables.tablestart(::RegressionTables.AbstractLatex, align) = "\\begin{tabular*}{\\linewidth}{$(align[1])@{\\extracolsep{\\fill}}$(align[2:end])}"
RegressionTables.tableend(::RegressionTables.AbstractLatex) = "\\end{tabular*}"
```
These two lines change all [`AbstractLatex`](@ref) tables.

The Julia type system also allows customization for more individualized tables. For example, you might include some descriptive tables in a paper, but it might make sense to use different rounding for descriptive data (such as making sure floats that are stored as integers are displayed as integers or rounding for large numbers). This needs to happen without changing the rounding in most tables. To do so, you can create a new type and set the display option for that type:
```julia
struct LatexDescriptiveTable <: RegressionTables.AbstractLatex end
function Base.repr(::LatexDescriptiveTable, x::Float64; args...)
if isinteger(x)
format(Int(x); commas=true)
else
precision = x > 1000 ? 1 : 3
format(x; commas=true, precision)
end
end
```

Now, when creating a descriptive table (see [`RegressionTable`](@ref) for an example), pass `render=LatexDescriptiveTable()` to use your formatting function.

The rest of this page goes through the defaults, showing what they are and what you might change each to.

## Rounding Digits

```@docs
RegressionTables.default_digits
```

## Default Keyword Arguments

```@docs
RegressionTables.default_section_order
RegressionTables.default_align
RegressionTables.default_header_align
RegressionTables.default_depvar
RegressionTables.default_number_regressions
RegressionTables.default_print_fe
RegressionTables.default_groups
RegressionTables.default_extralines
RegressionTables.default_keep
RegressionTables.default_drop
RegressionTables.default_order
RegressionTables.default_fixedeffects
RegressionTables.default_labels
RegressionTables.default_transform_labels
RegressionTables.default_below_statistic
RegressionTables.default_stat_below
RegressionTables.default_render
RegressionTables.default_file
RegressionTables.default_print_fe_suffix
RegressionTables.default_print_control_indicator
RegressionTables.default_standardize_coef
RegressionTables.default_print_estimator
RegressionTables.default_regression_statistics
RegressionTables.default_print_randomeffects
RegressionTables.default_print_clusters
```

## Other Defaults

While the user can adjust almost any part of this package (see [How Types are Displayed](@ref)), here are the remaining major defaults that are settable.

```@docs
RegressionTables.default_breaks
RegressionTables.default_symbol
RegressionTables.interaction_combine
RegressionTables.categorical_equal
RegressionTables.random_effect_separator
RegressionTables.estim_decorator
RegressionTables.below_decoration
RegressionTables.number_regressions_decoration
RegressionTables.fe_suffix
RegressionTables.wrapper
RegressionTables.fe_value
RegressionTables.cluster_suffix
```

## Labels

Labels are customizable by running the function that defines them. This makes it possible to change the labels once and then not worry about them on subsequent tables. To change a label, run:
```julia
RegressionTables.label(render::AbstractRenderType, ::Type{Nobs}) = "Obs."
```
Labels use the Julia type system, so it is possible to create different labels depending on the table type. This is done by default for cases such as [`Nobs`](@ref) and [`R2`](@ref), where the defaults for Latex and HTML are different. In such cases, it is necessary to set the label for all types that are used:
```julia
RegressionTables.label(render::AbstractLatex, ::Type{Nobs}) = "Obs."
RegressionTables.label(render::AbstractHtml, ::Type{Nobs}) = "Obs."
```

Some labels (notably the [`R2`](@ref) group), call another label function. For example:
```julia
label(render::AbstractRenderType, ::Type{AdjR2}) = "Adjusted " * label(render, R2)
```
Ths means that the label for [`AdjR2`](@ref) relies on the label for [`R2`](@ref). This also means that changing the label for [`R2`](@ref) will change the labels for all other `R2` types.
```@docs
RegressionTables.label
RegressionTables.label_p
RegressionTables.label_ols
RegressionTables.label_iv
RegressionTables.label_distribution
```
Loading

2 comments on commit c80aea9

@junder873
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/96466

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.0 -m "<description of version>" c80aea91c6f567a4b16b72e8becf11d293d62b6a
git push origin v0.6.0

Please sign in to comment.