Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -59,8 +59,8 @@ jobs:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'

steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v4
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ repos:
- id: mypy
args: [--ignore-missing-imports]
files: ^pyfixest/
additional_dependencies: [numpy>=1.20, pandas-stubs]
additional_dependencies: [numpy>=1.20, pandas-stubs]
24 changes: 12 additions & 12 deletions DTable.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
"outputs": [],
"source": [
"# Import necessary libraries\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"import maketables as mt\n",
"\n",
"# Load sample dataset\n",
Expand All @@ -56,11 +56,11 @@
" \"tenure\": \"Years of Tenure\",\n",
" \"occupation\": \"Occupation\",\n",
" \"worker_type\": \"Worker Type\",\n",
" \"education\": \"Education Level\"\n",
" \"education\": \"Education Level\",\n",
"}\n",
"\n",
"# Set default labels \n",
"mt.MTable.DEFAULT_LABELS = labels\n"
"# Set default labels\n",
"mt.MTable.DEFAULT_LABELS = labels"
]
},
{
Expand Down Expand Up @@ -706,7 +706,7 @@
"mt.DTable(\n",
" df,\n",
" vars=[\"wage\", \"logwage\", \"age\", \"tenure\"],\n",
" bycol=[\"worker_type\",\"gender\"],\n",
" bycol=[\"worker_type\", \"gender\"],\n",
" stats=[\"count\", \"mean\", \"std\"],\n",
" caption=\"Descriptive statistics by worker type and gender\",\n",
" stats_labels={\"count\": \"Number of observations\"},\n",
Expand Down Expand Up @@ -1407,19 +1407,19 @@
"source": [
"# Custom format specifications\n",
"format_specs = {\n",
" 'mean': ',.2f', # Comma separators, no decimals for means\n",
" 'std': '.2f', # 2 decimal places for standard deviations\n",
" 'count': ',.0f', # Comma separators for counts\n",
" 'min': ',.0f', # No decimals for min/max\n",
" 'max': ',.0f'\n",
" \"mean\": \",.2f\", # Comma separators, no decimals for means\n",
" \"std\": \".2f\", # 2 decimal places for standard deviations\n",
" \"count\": \",.0f\", # Comma separators for counts\n",
" \"min\": \",.0f\", # No decimals for min/max\n",
" \"max\": \",.0f\",\n",
"}\n",
"\n",
"mt.DTable(\n",
" df,\n",
" vars=[\"wage\", \"age\",\"tenure\"],\n",
" vars=[\"wage\", \"age\", \"tenure\"],\n",
" stats=[\"mean\", \"std\", \"min\", \"max\", \"count\"],\n",
" format_spec=format_specs,\n",
" caption=\"Custom formatting example\"\n",
" caption=\"Custom formatting example\",\n",
")"
]
}
Expand Down
76 changes: 46 additions & 30 deletions DocxTables.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@
"outputs": [],
"source": [
"# Import necessary libraries\n",
"import numpy as np\n",
"import pandas as pd\n",
"import pyfixest as pf\n",
"import statsmodels.formula.api as smf\n",
"\n",
"import maketables as mt\n",
"\n",
"# Load sample dataset\n",
Expand All @@ -87,10 +87,10 @@
" \"occupation\": \"Occupation\",\n",
" \"worker_type\": \"Worker Type\",\n",
" \"education\": \"Education Level\",\n",
" \"promoted\": \"Promotion\"\n",
" \"promoted\": \"Promotion\",\n",
"}\n",
"\n",
"# Set default labels \n",
"# Set default labels\n",
"mt.MTable.DEFAULT_LABELS = labels\n",
"\n",
"# Generate a categorical variable for gender from the dummy variable\n",
Expand Down Expand Up @@ -120,12 +120,18 @@
"outputs": [],
"source": [
"# Descriptive statistics\n",
"tab1 = mt.DTable(df, vars=[\"wage\", \"age\", \"tenure\"],\n",
" bycol=[\"worker_type\"], byrow=\"gender\",\n",
" stats=[\"count\", \"mean\", \"std\"],\n",
" caption=\"Descriptive statistics by worker type and gender\",\n",
" format_spec = {'mean': ',.2f', 'std': '.2f',})\n",
"\n"
"tab1 = mt.DTable(\n",
" df,\n",
" vars=[\"wage\", \"age\", \"tenure\"],\n",
" bycol=[\"worker_type\"],\n",
" byrow=\"gender\",\n",
" stats=[\"count\", \"mean\", \"std\"],\n",
" caption=\"Descriptive statistics by worker type and gender\",\n",
" format_spec={\n",
" \"mean\": \",.2f\",\n",
" \"std\": \".2f\",\n",
" },\n",
")"
]
},
{
Expand Down Expand Up @@ -162,8 +168,12 @@
"outputs": [],
"source": [
"# Fill/update the first table in the document to display the descriptive statistics:\n",
"tab1.update_docx(file_name=\"docs/WordOutput.docx\", tab_num=1, \n",
" show=False, docx_style={\"first_col_width\": \"5cm\"})"
"tab1.update_docx(\n",
" file_name=\"docs/WordOutput.docx\",\n",
" tab_num=1,\n",
" show=False,\n",
" docx_style={\"first_col_width\": \"5cm\"},\n",
")"
]
},
{
Expand All @@ -190,8 +200,10 @@
"source": [
"# Here we use (py)fixest's stepwise notation to estimate several regressions in one go\n",
"# And directly generate a regression table with the results\n",
"tab2=mt.ETable(pf.feols(\"logwage+wage~ age + female + sw0(age:female)\", data=df),\n",
" caption=\"Wage regressions\")\n",
"tab2 = mt.ETable(\n",
" pf.feols(\"logwage+wage~ age + female + sw0(age:female)\", data=df),\n",
" caption=\"Wage regressions\",\n",
")\n",
"\n",
"# Fill/update the second table in the document\n",
"tab2.update_docx(file_name=\"docs/WordOutput.docx\", tab_num=2, show=False)"
Expand Down Expand Up @@ -219,17 +231,18 @@
},
"outputs": [],
"source": [
"\n",
"# Fit your models \n",
"# Fit your models\n",
"est1 = smf.ols(\"promoted ~ tenure + female + worker_type\", data=df).fit()\n",
"est2 = smf.probit(\"promoted ~ tenure + female + worker_type\", data=df).fit(disp=0)\n",
"\n",
"# Make the table\n",
"tab3= mt.ETable([est1, est2],\n",
" keep=[\"Intercept\", \"tenure\", \"female\", \"worker_type\"],\n",
" model_stats=[\"N\",\"r2\",\"pseudo_r2\"],\n",
" model_heads=[\"OLS\",\"Probit\"],\n",
" caption=\"Predicting Promotions\")\n",
"tab3 = mt.ETable(\n",
" [est1, est2],\n",
" keep=[\"Intercept\", \"tenure\", \"female\", \"worker_type\"],\n",
" model_stats=[\"N\", \"r2\", \"pseudo_r2\"],\n",
" model_heads=[\"OLS\", \"Probit\"],\n",
" caption=\"Predicting Promotions\",\n",
")\n",
"\n",
"# Fill/update the third table in the document\n",
"tab3.update_docx(file_name=\"docs/WordOutput.docx\", tab_num=3, show=False)"
Expand Down Expand Up @@ -302,13 +315,15 @@
"source": [
"# Example: Change global defaults\n",
"# Set a different default font and first column width\n",
"mt.MTable.DEFAULT_DOCX_STYLE.update({\n",
" \"font_name\": \"Calibri\",\n",
" \"font_size_pt\": 10,\n",
" \"first_col_width\": \"3cm\",\n",
" \"border_top_rule_sz\": 12, # Thicker top border\n",
" \"caption_align\": \"right\"\n",
"})"
"mt.MTable.DEFAULT_DOCX_STYLE.update(\n",
" {\n",
" \"font_name\": \"Calibri\",\n",
" \"font_size_pt\": 10,\n",
" \"first_col_width\": \"3cm\",\n",
" \"border_top_rule_sz\": 12, # Thicker top border\n",
" \"caption_align\": \"right\",\n",
" }\n",
")"
]
},
{
Expand Down Expand Up @@ -343,10 +358,11 @@
" \"caption_align\": \"left\",\n",
"}\n",
"\n",
"# Apply custom style to a specific table, \n",
"# Apply custom style to a specific table,\n",
"# Here we just add the last table again as now fourth table in the document with a different style:\n",
"tab3.update_docx(file_name=\"docs/WordOutput.docx\", tab_num=4, show=False, \n",
" docx_style=custom_style)"
"tab3.update_docx(\n",
" file_name=\"docs/WordOutput.docx\", tab_num=4, show=False, docx_style=custom_style\n",
")"
]
}
],
Expand Down
54 changes: 33 additions & 21 deletions ETable.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@
"outputs": [],
"source": [
"# Import necessary libraries\n",
"import numpy as np\n",
"import pandas as pd\n",
"import pyfixest as pf\n",
"import statsmodels.formula.api as smf\n",
"\n",
"import maketables as mt\n",
"\n",
"# Load sample dataset\n",
Expand All @@ -52,7 +51,7 @@
"est1 = pf.feols(\"logwage ~ age\", data=df)\n",
"est2 = pf.feols(\"logwage ~ age + female\", data=df)\n",
"est3 = pf.feols(\"logwage ~ age + female | worker_type\", data=df)\n",
"est4 = pf.feols(\"logwage ~ age + female | worker_type + occupation\", data=df)\n"
"est4 = pf.feols(\"logwage ~ age + female | worker_type + occupation\", data=df)"
]
},
{
Expand Down Expand Up @@ -1404,7 +1403,7 @@
}
],
"source": [
"mt.ETable([est1, est2, est3, est4], model_stats=['N','r2','r2_within'])"
"mt.ETable([est1, est2, est3, est4], model_stats=[\"N\", \"r2\", \"r2_within\"])"
]
},
{
Expand Down Expand Up @@ -1633,7 +1632,11 @@
}
],
"source": [
"mt.ETable([est1, est2, est3, est4], model_stats=['N','r2'], model_stats_labels={\"N\": \"Number of observations\", \"r2\": \"R squared\"})"
"mt.ETable(\n",
" [est1, est2, est3, est4],\n",
" model_stats=[\"N\", \"r2\"],\n",
" model_stats_labels={\"N\": \"Number of observations\", \"r2\": \"R squared\"},\n",
")"
]
},
{
Expand Down Expand Up @@ -1839,7 +1842,7 @@
}
],
"source": [
"mt.ETable([est1, est2, est3, est4], model_stats=['r2','N'], show_fe=False)"
"mt.ETable([est1, est2, est3, est4], model_stats=[\"r2\", \"N\"], show_fe=False)"
]
},
{
Expand Down Expand Up @@ -2734,7 +2737,7 @@
" \"tenure\": \"Years of Tenure\",\n",
" \"occupation\": \"Occupation\",\n",
" \"worker_type\": \"Worker Type\",\n",
" \"education\": \"Education Level\"\n",
" \"education\": \"Education Level\",\n",
"}\n",
"\n",
"mt.ETable([est1, est2, est3, est4], labels=labels)"
Expand Down Expand Up @@ -2969,7 +2972,10 @@
"mt.ETable(\n",
" [est1, est2, est3, est4],\n",
" labels=labels,\n",
" felabels={\"occupation\": \"Occupation Fixed Effects\", \"worker_type\": \"Worker Type Fixed Effects\"},\n",
" felabels={\n",
" \"occupation\": \"Occupation Fixed Effects\",\n",
" \"worker_type\": \"Worker Type Fixed Effects\",\n",
" },\n",
")"
]
},
Expand All @@ -2995,9 +3001,9 @@
"outputs": [],
"source": [
"# Set default options for all future ETable calls\n",
"mt.ETable.DEFAULT_MODEL_STATS = [\"N\",\"r2\",\"r2_within\"]\n",
"mt.ETable.DEFAULT_MODEL_STATS = [\"N\", \"r2\", \"r2_within\"]\n",
"mt.ETable.DEFAULT_COEF_FMT = \"b:.3f \\n (se:.3f)\"\n",
"mt.ETable.DEFAULT_SIGNIF_CODE = [0.01, 0.05, 0.1]\n"
"mt.ETable.DEFAULT_SIGNIF_CODE = [0.01, 0.05, 0.1]"
]
},
{
Expand All @@ -3020,7 +3026,7 @@
},
"outputs": [],
"source": [
"# Note: Default labels are set as class attribute of MTable \n",
"# Note: Default labels are set as class attribute of MTable\n",
"mt.MTable.DEFAULT_LABELS = labels"
]
},
Expand Down Expand Up @@ -3478,9 +3484,9 @@
}
],
"source": [
"est5 = pf.feols(\"logwage ~ age + female + education\", data = df)\n",
"est5 = pf.feols(\"logwage ~ age + female + education\", data=df)\n",
"\n",
"mt.ETable([est5], cat_template = \"{variable}: {value}\")"
"mt.ETable([est5], cat_template=\"{variable}: {value}\")"
]
},
{
Expand Down Expand Up @@ -3745,10 +3751,10 @@
}
],
"source": [
"est6 = pf.feols(\"logwage ~ age + female + education\", data = df)\n",
"est7 = pf.feols(\"logwage ~ age + female + education*age\", data = df)\n",
"est6 = pf.feols(\"logwage ~ age + female + education\", data=df)\n",
"est7 = pf.feols(\"logwage ~ age + female + education*age\", data=df)\n",
"\n",
"mt.ETable([est6, est7], cat_template=\"{value}\")"
"mt.ETable([est6, est7], cat_template=\"{value}\")"
]
},
{
Expand Down Expand Up @@ -4270,10 +4276,11 @@
"mod3 = pf.feols(\"logwage ~ age + female | worker_type + occupation\", data=df)\n",
"mod4 = pf.feols(\"wage ~ age + female | worker_type + occupation\", data=df)\n",
"\n",
"mt.ETable([mod1, mod2, mod3, mod4], \n",
" model_heads=[\"OLS\", \"OLS\", \"Fixed Effects\", \"Fixed Effects\"], \n",
" head_order=\"hd\")\n",
" "
"mt.ETable(\n",
" [mod1, mod2, mod3, mod4],\n",
" model_heads=[\"OLS\", \"OLS\", \"Fixed Effects\", \"Fixed Effects\"],\n",
" head_order=\"hd\",\n",
")"
]
},
{
Expand Down Expand Up @@ -4749,7 +4756,12 @@
" show_fe=False,\n",
" custom_model_stats={\n",
" \"Fixed Effects\": [\"No\", \"No\", \"Worker Type\", \"Worker Type & Occupation\"],\n",
" \"Data Type\": [\"Cross-section\", \"Cross-section\", \"Cross-section\", \"Cross-section\"],\n",
" \"Data Type\": [\n",
" \"Cross-section\",\n",
" \"Cross-section\",\n",
" \"Cross-section\",\n",
" \"Cross-section\",\n",
" ],\n",
" },\n",
")"
]
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
Loading