diff --git a/module3/exo3/exercice_en.ipynb b/module3/exo3/exercice_en.ipynb
index 0bbbe371b01e359e381e43239412d77bf53fb1fb..ccc2812356fefcefdab74c88bfd68339c1ecc087 100644
--- a/module3/exo3/exercice_en.ipynb
+++ b/module3/exo3/exercice_en.ipynb
@@ -1,5 +1,1901 @@
{
- "cells": [],
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Smoker | \n",
+ " Status | \n",
+ " Age | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Yes | \n",
+ " Alive | \n",
+ " 21.0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Yes | \n",
+ " Alive | \n",
+ " 19.3 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " No | \n",
+ " Dead | \n",
+ " 57.5 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " No | \n",
+ " Alive | \n",
+ " 47.1 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " Yes | \n",
+ " Alive | \n",
+ " 81.4 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Smoker Status Age\n",
+ "0 Yes Alive 21.0\n",
+ "1 Yes Alive 19.3\n",
+ "2 No Dead 57.5\n",
+ "3 No Alive 47.1\n",
+ "4 Yes Alive 81.4"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "df = pd.read_csv(\"../../Subject6_smoking.csv\")\n",
+ "df.head()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Smoker Status Age\n",
+ "0 Yes Alive 21.0\n",
+ "1 Yes Alive 19.3\n",
+ "2 No Dead 57.5\n",
+ "3 No Alive 47.1\n",
+ "4 Yes Alive 81.4\n",
+ "Status Alive Dead\n",
+ "Smoker \n",
+ "No 502 230\n",
+ "Yes 443 139\n",
+ "Smoker\n",
+ "No 49.815847\n",
+ "Yes 44.269759\n",
+ "Name: Age, dtype: float64\n",
+ "Smoker Status\n",
+ "No Alive 40.347410\n",
+ " Dead 70.481739\n",
+ "Yes Alive 39.648984\n",
+ " Dead 58.996403\n",
+ "Name: Age, dtype: float64\n"
+ ]
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "# Load the dataset\n",
+ "df = pd.read_csv(\"../../Subject6_smoking.csv\")\n",
+ "\n",
+ "# Quick look at the first rows\n",
+ "print(df.head())\n",
+ "\n",
+ "# Summary by smoker status\n",
+ "summary = df.groupby(\"Smoker\")[\"Status\"].value_counts().unstack()\n",
+ "print(summary)\n",
+ "\n",
+ "# Mean age by smoker status\n",
+ "mean_age = df.groupby(\"Smoker\")[\"Age\"].mean()\n",
+ "print(mean_age)\n",
+ "\n",
+ "# Check by smoker *and* status to see the paradox\n",
+ "cross_summary = df.groupby([\"Smoker\", \"Status\"])[\"Age\"].mean()\n",
+ "print(cross_summary)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "# Side-by-side boxplots\n",
+ "plt.figure(figsize=(8,5))\n",
+ "sns.boxplot(data=df, x=\"Smoker\", y=\"Age\", hue=\"Status\")\n",
+ "plt.title(\"Age distribution by Smoker status and Survival\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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3zctAl5/5z1++sxS1m3akkN11tlmzpxJRPJvPiJ47LHHuPLKK3OuqjgyC3JJ/YHNaYj3Bs4AvgdMB+qAG9LHB7OqwawSvP766+y5554MHToUSXmX0yGWLl3Khk2b2dpr7/dNiwj267uOrwK3zPlj5xdnnW7gwIEsWbJku2ErX5Yt8kFAvaQqki78eyLiYUnPAPdIughYCnwxwxp2qmrD2/R+5ZE8Syhbj/fWArC11145V1Keqg1vA/6D/KDee++9igrxnZHEbn32ZMg+vfIuxTrJm2++ucNh27HMgjwiFgDHtDK+ETg9q+22R01NTd4ltEtDwzoAag4pSjgOLNxz3FV1lxBvJolutsvd2oc//OHtWuQf/vCH8yumgDrlHHlXNX78+LxLaJeJEycCcPPNN+dciRXN9ddfz5133klVVRU9evTghz/8Ic888wyXXHIJffr02eGyN910U1nzme2qlStX7nDYdsyXaDWrcM888wwPP/ww8+bNY8GCBTz++OMccMAB3HTTTWzYsGGny5c7n9muGjVq1LZeJ0mceeaZOVdULA5yswq3YsUK+vXrx4c+9CEA+vXrx3333ccbb7zBaaedxmmnnQbA1772NWpraznyyCP5zne+A8Att9zyvvn22GOPbeu+7777uPDCCwG49957Oeqoozj66KM59dRTO3EPrejq6uro2bMnAD179uSCCy7IuaJicZCbVbgzzzyTZcuWceihh3LZZZfxxBNPMGHCBPbff39mz57N7NmzgaT7fe7cuSxYsIAnnniCBQsWtDpfW7773e/yi1/8gt/+9rdMnz69M3bNKkTfvn0ZPXo0kjjrrLPo27dv3iUVioPcrMLtsccePP/880yZMoX+/fszbtw4br/99vfNd8899zBixAiOOeYYXnrpJV5++eV2beekk07iwgsv5Ec/+hFbtvj739Y+Y8aMoU+fPpxzzjl5l1I4DnKzbqCqqoqRI0dy7bXXcuutt3L//fdvN/2Pf/wjN954I7NmzWLBggV89rOfbfMCNKWfoC+d57bbbuO6665j2bJlDB8+3JfZtHaZPn06GzZs4KGHHsq7lMLp1p9aN+sOfve739GjRw+GDRsGwPz58znooINYsmQJ69ato1+/fqxdu5bdd9+dvffem5UrV/Loo48ycuRIAPbcc89t80FysY5FixZx2GGHMW3aNPbcc08A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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "%matplotlib inline\n",
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "plt.figure(figsize=(8,5))\n",
+ "sns.boxplot(data=df, x=\"Smoker\", y=\"Age\", hue=\"Status\")\n",
+ "plt.title(\"Age distribution by Smoker status and Survival\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Status Alive Dead Mortality Rate\n",
+ "Smoker \n",
+ "No 502 230 0.314208\n",
+ "Yes 443 139 0.238832\n"
+ ]
+ }
+ ],
+ "source": [
+ "summary = df.groupby(\"Smoker\")[\"Status\"].value_counts().unstack()\n",
+ "summary[\"Mortality Rate\"] = summary[\"Dead\"] / summary.sum(axis=1)\n",
+ "print(summary)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Status Alive Dead Mortality Rate\n",
+ "AgeGroup Smoker \n",
+ "18–34 No 212 6 0.027523\n",
+ " Yes 172 5 0.028249\n",
+ "34–54 No 180 19 0.095477\n",
+ " Yes 196 41 0.172996\n",
+ "55–64 No 81 40 0.330579\n",
+ " Yes 64 51 0.443478\n",
+ "65+ No 28 165 0.854922\n",
+ " Yes 7 42 0.857143\n"
+ ]
+ }
+ ],
+ "source": [
+ "bins = [18, 34, 54, 64, 120]\n",
+ "labels = [\"18–34\", \"34–54\", \"55–64\", \"65+\"]\n",
+ "df[\"AgeGroup\"] = pd.cut(df[\"Age\"], bins=bins, labels=labels, right=True)\n",
+ "\n",
+ "age_summary = df.groupby([\"AgeGroup\", \"Smoker\"])[\"Status\"].value_counts().unstack()\n",
+ "age_summary[\"Mortality Rate\"] = age_summary[\"Dead\"] / age_summary.sum(axis=1)\n",
+ "print(age_summary)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ValueError",
+ "evalue": "Neither the `x` nor `y` variable appears to be numeric.",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m8\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbarplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Smoker\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Status\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m==\u001b[0m\u001b[0;34m\"Dead\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mestimator\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Mortality Rate\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Overall mortality rate by smoking status\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mbarplot\u001b[0;34m(x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, orient, color, palette, saturation, errcolor, errwidth, capsize, dodge, ax, **kwargs)\u001b[0m\n\u001b[1;32m 2957\u001b[0m \u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2958\u001b[0m \u001b[0morient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2959\u001b[0;31m errcolor, errwidth, capsize, dodge)\n\u001b[0m\u001b[1;32m 2960\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2961\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0max\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, orient, color, palette, saturation, errcolor, errwidth, capsize, dodge)\u001b[0m\n\u001b[1;32m 1594\u001b[0m \u001b[0;34m\"\"\"Initialize the plotter.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1595\u001b[0m self.establish_variables(x, y, hue, data, orient,\n\u001b[0;32m-> 1596\u001b[0;31m order, hue_order, units)\n\u001b[0m\u001b[1;32m 1597\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestablish_colors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1598\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestimate_statistic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mestablish_variables\u001b[0;34m(self, x, y, hue, data, orient, order, hue_order, units)\u001b[0m\n\u001b[1;32m 152\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 153\u001b[0m \u001b[0;31m# Figure out the plotting orientation\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 154\u001b[0;31m \u001b[0morient\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfer_orient\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0morient\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 155\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 156\u001b[0m \u001b[0;31m# Option 2a:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36minfer_orient\u001b[0;34m(self, x, y, orient)\u001b[0m\n\u001b[1;32m 355\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mis_not_numeric\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 356\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_not_numeric\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 357\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mno_numeric\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 358\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 359\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m\"h\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Neither the `x` nor `y` variable appears to be numeric."
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "\n",
+ "plt.figure(figsize=(8,5))\n",
+ "sns.barplot(data=df, x=\"Smoker\", y=(df[\"Status\"]==\"Dead\"), estimator=lambda x: sum(x)/len(x))\n",
+ "plt.ylabel(\"Mortality Rate\")\n",
+ "plt.title(\"Overall mortality rate by smoking status\")\n",
+ "plt.show()\n",
+ "\n",
+ "plt.figure(figsize=(10,6))\n",
+ "sns.barplot(data=df, x=\"AgeGroup\", y=(df[\"Status\"]==\"Dead\"), hue=\"Smoker\",\n",
+ " estimator=lambda x: sum(x)/len(x))\n",
+ "plt.ylabel(\"Mortality Rate\")\n",
+ "plt.title(\"Mortality rate by age group and smoking status\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/opt/conda/lib/python3.6/site-packages/scipy/stats/stats.py:1713: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.\n",
+ " return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "df[\"Death\"] = (df[\"Status\"] == \"Dead\").astype(int)\n",
+ "\n",
+ "plt.figure(figsize=(8,5))\n",
+ "sns.barplot(data=df, x=\"Smoker\", y=\"Death\", estimator=lambda x: x.mean())\n",
+ "plt.ylabel(\"Mortality Rate\")\n",
+ "plt.title(\"Overall mortality rate by smoking status\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ValueError",
+ "evalue": "Neither the `x` nor `y` variable appears to be numeric.",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m8\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbarplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Smoker\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Status\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m==\u001b[0m\u001b[0;34m\"Dead\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mestimator\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mylabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Mortality Rate\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtitle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Overall mortality rate by smoking status\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mbarplot\u001b[0;34m(x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, orient, color, palette, saturation, errcolor, errwidth, capsize, dodge, ax, **kwargs)\u001b[0m\n\u001b[1;32m 2957\u001b[0m \u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munits\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2958\u001b[0m \u001b[0morient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2959\u001b[0;31m errcolor, errwidth, capsize, dodge)\n\u001b[0m\u001b[1;32m 2960\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2961\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0max\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, x, y, hue, data, order, hue_order, estimator, ci, n_boot, units, orient, color, palette, saturation, errcolor, errwidth, capsize, dodge)\u001b[0m\n\u001b[1;32m 1594\u001b[0m \u001b[0;34m\"\"\"Initialize the plotter.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1595\u001b[0m self.establish_variables(x, y, hue, data, orient,\n\u001b[0;32m-> 1596\u001b[0;31m order, hue_order, units)\n\u001b[0m\u001b[1;32m 1597\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestablish_colors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpalette\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaturation\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1598\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mestimate_statistic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mestimator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mci\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_boot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36mestablish_variables\u001b[0;34m(self, x, y, hue, data, orient, order, hue_order, units)\u001b[0m\n\u001b[1;32m 152\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 153\u001b[0m \u001b[0;31m# Figure out the plotting orientation\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 154\u001b[0;31m \u001b[0morient\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfer_orient\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0morient\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 155\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 156\u001b[0m \u001b[0;31m# Option 2a:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/seaborn/categorical.py\u001b[0m in \u001b[0;36minfer_orient\u001b[0;34m(self, x, y, orient)\u001b[0m\n\u001b[1;32m 355\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mis_not_numeric\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 356\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_not_numeric\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 357\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mno_numeric\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 358\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 359\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m\"h\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Neither the `x` nor `y` variable appears to be numeric."
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "\n",
+ "plt.figure(figsize=(8,5))\n",
+ "sns.barplot(data=df, x=\"Smoker\", y=(df[\"Status\"]==\"Dead\"), estimator=lambda x: sum(x)/len(x))\n",
+ "plt.ylabel(\"Mortality Rate\")\n",
+ "plt.title(\"Overall mortality rate by smoking status\")\n",
+ "plt.show()\n",
+ "\n",
+ "plt.figure(figsize=(10,6))\n",
+ "sns.barplot(data=df, x=\"AgeGroup\", y=(df[\"Status\"]==\"Dead\"), hue=\"Smoker\",\n",
+ " estimator=lambda x: sum(x)/len(x))\n",
+ "plt.ylabel(\"Mortality Rate\")\n",
+ "plt.title(\"Mortality rate by age group and smoking status\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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Xsm9997L3LlzmTVrFh/96Ed5+eWX3zPvypUrW225kiSpY+kUgWz58uU8/PDD/OQnP1kjkK1atYovfOELDBgwgNGjRzNq1Chuv/12AGbOnMkBBxzAnnvuyYgRI3jppfdes/biiy/m8ssvZ9tts1twdunShXHjxrHbbrsBUFVVxde//nWGDRvGbbfdRm1tLfvssw+DBw9mzJgxvPrqqwAMHz6c1XcfWLJkCVVVVQBMnDiRww47jJEjR7Lbbrtx0UUXVWwbSZKk4nSKQHbXXXcxcuRIdt11VzbffHNmzZoFwJ133smCBQt48sknuf7663nkkUeA7DIap512GrfffjszZ85k3LhxfPWrX31Pu3PnzmWPPfZodtk9evRg2rRpHH300Rx33HF8+9vfZvbs2QwaNKisgDV9+nR+9rOfUVtby2233Ya3jZIkqePpFIHslltu4eijjwbg6KOP5pZbbgFg2rRpHHnkkWywwQZstdVWHHjggQA8/fTTzJkzh4MOOojq6mq++c1vsnDhwmaX8eSTT1JdXc3OO+/ML37xi/rxn/70pwF47bXXWLZsGQcccAAAxx9/PFOnTl1r7QcddBB9+vRho4024ogjjmDatGkt3wCSJKlN6xDXIWvO0qVLefDBB5kzZw4RwcqVK4kILrvsMrKbBbxXSokBAwbU95g1ZcCAAcyaNYsDDzyQQYMGUVtby6mnnsrbb79dP8/GG2+81hq7du3KqlWrAN5z2YqGZ056JqUkSR1Ph+8hu/322znuuON4/vnnWbBgAS+++CI77rgj06ZNY9iwYdxxxx2sWrWKl19+mSlTpgCw2267sXjx4jV2Yc6dO/c9bZ933nmcffbZa/SelYaxUptuuimbbbYZf/zjHwGYNGlSfW9ZVVUVM2fOrK+31O9+9zv++c9/8vbbb3PXXXex3377vb8NIkmS2pwO30N2yy238JWvfGWNcZ/85Cf5+c9/ztVXX80DDzzAwIED2XXXXRk6dCibbrop3bt35/bbb+f000/ntddeo66uji996UsMGDBgjXZGjRrF4sWLOfjgg1m5ciW9e/dm4MCBjBgxotFabrrpJk455RTeeustdtppJ2688UYAzj77bI466igmTZrExz72sTVeM2zYMD73uc8xb948jjnmGGpqalpx60iSpLYgmtpt11bV1NSkhge2P/XUU/Tv33+d2lu+fDm9evVi6dKl7L333jz88MNstdVWrVHq+zZx4kRmzJjBVVddVfZr3s+2kCRJrSsiZqaU1tqb0uF7yNZm9OjRLFu2jHfeeYcJEya0mTAmSZI6j04fyFYfN9YWjR07lrFjxxZdhiRJqrAOf1C/JElSW2cgkyRJKpiBTJIkqWAGMkmSpIIZyFrJuHHj2HLLLRk4cGD9uNU3E6+urqampobp06c3+frp06dTXV1NdXU1Q4YMYfLkye+Z59BDD12jfUmS1DF0yLMs9/yfm1u1vZnfOW6t84wdO5ZTTz2V447797znnHMOX/va1zj44IO55557OOecc5o8q3PgwIHMmDGDrl278tJLLzFkyBA+8YlP0LVr9hbdeeed9OrVq1XWR5IktS32kLWS/fffn80333yNcRHB66+/DmQ3F99mm22afH3Pnj3rw9eKFSvWuGfl8uXLueKKKzj//PMrULkkSSpah+whayu++93vMmLECM4++2xWrVrFn/70p2bnf+yxxxg3bhzPP/88kyZNqg9oEyZM4KyzzqJnz57ro2xJkrSe2UNWQT/60Y+48sorefHFF7nyyiv5/Oc/3+z8Q4cOZe7cuTz++ON861vfYsWKFdTW1jJv3jzGjBmznqqWJEnrm4Gsgm666SaOOOIIAI488sj6g/pPOOGE+gP4q6ureeyxx9Z4Xf/+/dl4442ZM2cOjzzyCDNnzqSqqophw4bxzDPPMHz48PW9KpIkqYLcZVlB22yzDQ899BDDhw/nwQcfZJdddgHgxhtvfM+8zz33HNtttx1du3bl+eef5+mnn6aqqoqamhrGjx8PwIIFCxg9enSbvt2TJElqOQNZK/nMZz7DlClTWLJkCf369eOiiy7ixz/+MWeccQZ1dXX06NGD6667rsnXT5s2jUsvvZRu3bqxwQYb8MMf/pC+ffuuxzWQJElFiZRS0TW0SE1NTZoxY8Ya45566in69+9fUEVti9tCkqS2IyJmppRq1jafx5BJkiQVzEAmSZJUMAOZJElSwQxkkiRJBTOQSZIkFcxAJkmSVDADWStZsWIFe++9N0OGDGHAgAF87WtfW2P65ZdfTkSwZMmSJttYsGABG220Uf0V/E855ZT3zHPooYcycODAVq9fkiQVp0NeGPaFrw9q1fa2v+DJtc6z4YYb8uCDD9KrVy/effddhg0bxsEHH8w+++zDiy++yO9+9zu23377tbaz8847U1tb2+i0O++8k169erW4fkmS1LbZQ9ZKIqI+LL377ru8++67RAQAZ555Jpdddln98LpYvnw5V1xxBeeff36r1CtJktoOA1krWrlyJdXV1Wy55ZYcdNBBDB06lLvvvpttt92WIUOGlNXGc889x0c+8hEOOOAA/vjHP9aPnzBhAmeddRY9e/asVPmSJKkgHXKXZVG6dOlCbW0ty5YtY8yYMcyePZuLL76Y+++/v6zXb7311rzwwgv06dOHmTNncvjhhzN37lzmz5/PvHnzuPLKK1mwYEFlV0KSJK13BrIK6N27N8OHD+dXv/oVzz33XH3v2MKFC9ljjz2YPn065513Hk888UT9a6699lqGDh3KhhtuCMCee+7JzjvvzDPPPMPjjz/OzJkzqaqqoq6ujldeeYXhw4czZcqUIlZPkiS1MgNZK1m8eDHdunWjd+/evP322/z+97/n3HPP5ZVXXqmfp6qqihkzZtC3b19uvPHGRtvYfPPN6dKlC/Pnz+dvf/sbO+20EzU1NYwfPx7IzsQcPXq0YUySpA7EQNZKXnrpJY4//nhWrlzJqlWrOOqooxg9enSL2pg6dSoXXHABXbt2pUuXLlxzzTVsvvnmFapYHcFD+x9QdAkVc8DUh4ouQZLWm0gpFV1Di9TU1KQZM2asMe6pp56if//+BVXUtrgtOhcDmaRK8G9L64mImSmlmrXN51mWkiRJBTOQSZIkFcxAJkmSVDADmSRJUsEMZJIkSQUzkEmSJBXMQNaKqqqqGDRoENXV1dTUZGe4XnjhhWy77bZUV1dTXV3NPffc02wbs2fPZt9992XAgAEMGjSIFStWrDH90EMPZeDAgRVbB0mStP51yAvD7veD/Vq1vYdPe7jsef/whz/Qt2/fNcadeeaZnH322Wt9bV1dHcceeyyTJk1iyJAhLF26lG7dutVPv/POO+nVq1f5hUuSpHbBHrI25P7772fw4MH1977s06cPXbp0AWD58uVcccUVnH/++UWWKEmSKsBA1ooigo9//OPsueeeXHfddfXjr7rqKgYPHsy4ceN49dVXm3z9M888Q0QwYsQI9thjDy677LL6aRMmTOCss86iZ8+eFV0HSZK0/hnIWtHDDz/MrFmzuPfee7n66quZOnUq48eP59lnn6W2tpatt96as846q8nX19XVMW3aNH72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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "import numpy as np\n",
+ "\n",
+ "# Numeric mortality flag\n",
+ "df[\"DeadFlag\"] = (df[\"Status\"] == \"Dead\").astype(int)\n",
+ "\n",
+ "# Define age groups\n",
+ "bins = [18, 34, 54, 64, df[\"Age\"].max()]\n",
+ "labels = [\"18–34\", \"34–54\", \"55–64\", \"65+\"]\n",
+ "df[\"AgeGroup\"] = pd.cut(df[\"Age\"], bins=bins, labels=labels, right=True, include_lowest=True)\n",
+ "\n",
+ "# Plot\n",
+ "plt.figure(figsize=(10, 6))\n",
+ "sns.barplot(\n",
+ " data=df,\n",
+ " x=\"Smoker\",\n",
+ " y=\"DeadFlag\",\n",
+ " hue=\"AgeGroup\",\n",
+ " estimator=np.mean,\n",
+ " ci=None\n",
+ ")\n",
+ "plt.ylabel(\"Mortality Rate\")\n",
+ "plt.title(\"Mortality rate by Smoking Status and Age Group\")\n",
+ "plt.ylim(0, 1)\n",
+ "plt.legend(title=\"Age Group\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(1314, 3)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Smoker | \n",
+ " Status | \n",
+ " Age | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Yes | \n",
+ " Alive | \n",
+ " 21.0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Yes | \n",
+ " Alive | \n",
+ " 19.3 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " No | \n",
+ " Dead | \n",
+ " 57.5 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " No | \n",
+ " Alive | \n",
+ " 47.1 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " Yes | \n",
+ " Alive | \n",
+ " 81.4 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Smoker Status Age\n",
+ "0 Yes Alive 21.0\n",
+ "1 Yes Alive 19.3\n",
+ "2 No Dead 57.5\n",
+ "3 No Alive 47.1\n",
+ "4 Yes Alive 81.4"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Cell 1 — Setup & load data\n",
+ "%matplotlib inline\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "import statsmodels.formula.api as smf\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "\n",
+ "sns.set(style=\"whitegrid\")\n",
+ "\n",
+ "# Adjust this path if necessary\n",
+ "data_path = \"../../Subject6_smoking.csv\"\n",
+ "\n",
+ "df = pd.read_csv(data_path)\n",
+ "# preview\n",
+ "print(df.shape)\n",
+ "df.head()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "No 732\n",
+ "Yes 582\n",
+ "Name: Smoker, dtype: int64\n",
+ "Alive 945\n",
+ "Dead 369\n",
+ "Name: Status, dtype: int64\n",
+ "Mean age: 47.35936073059361\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Cell 2 — Clean & prepare columns\n",
+ "# Standardize column names if needed\n",
+ "df.columns = [c.strip() for c in df.columns]\n",
+ "\n",
+ "# Create numeric death flag\n",
+ "df['Death'] = (df['Status'].str.strip().str.lower() == \"dead\").astype(int)\n",
+ "\n",
+ "# Make Smoker categorical with consistent labels\n",
+ "df['Smoker'] = df['Smoker'].str.strip().replace({'Yes':'Yes','No':'No'})\n",
+ "\n",
+ "# Basic checks\n",
+ "print(df['Smoker'].value_counts())\n",
+ "print(df['Status'].value_counts())\n",
+ "print(\"Mean age:\", df['Age'].mean())\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Overall counts and mortality rates by smoking status (with 95% CI):\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " alive | \n",
+ " dead | \n",
+ " total | \n",
+ " mortality_rate | \n",
+ " ci_lower | \n",
+ " ci_upper | \n",
+ "
\n",
+ " \n",
+ " | Smoker | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ " | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | No | \n",
+ " 502 | \n",
+ " 230 | \n",
+ " 732 | \n",
+ " 0.314208 | \n",
+ " 0.281624 | \n",
+ " 0.348731 | \n",
+ "
\n",
+ " \n",
+ " | Yes | \n",
+ " 443 | \n",
+ " 139 | \n",
+ " 582 | \n",
+ " 0.238832 | \n",
+ " 0.205976 | \n",
+ " 0.275112 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " alive dead total mortality_rate ci_lower ci_upper\n",
+ "Smoker \n",
+ "No 502 230 732 0.314208 0.281624 0.348731\n",
+ "Yes 443 139 582 0.238832 0.205976 0.275112"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Cell 3 — Step 1: Tabulate overall counts and mortality rates by smoking status\n",
+ "grouped = df.groupby('Smoker')['Death'].agg(['sum','count']).rename(columns={'sum':'dead','count':'total'})\n",
+ "grouped['alive'] = grouped['total'] - grouped['dead']\n",
+ "grouped['mortality_rate'] = grouped['dead'] / grouped['total']\n",
+ "\n",
+ "# 95% Wilson confidence intervals for proportion (more stable than plain normal)\n",
+ "cis = grouped.apply(lambda row: proportion_confint(count=int(row['dead']), nobs=int(row['total']), alpha=0.05, method='wilson'), axis=1)\n",
+ "grouped['ci_lower'] = [c[0] for c in cis]\n",
+ "grouped['ci_upper'] = [c[1] for c in cis]\n",
+ "\n",
+ "# Display nicely\n",
+ "display_cols = ['alive','dead','total','mortality_rate','ci_lower','ci_upper']\n",
+ "print(\"Overall counts and mortality rates by smoking status (with 95% CI):\")\n",
+ "grouped[display_cols]\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEXCAYAAACgUUN5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3XtYVOXeP/73cBIQ8xgMBtt8FM0nDyAn2RokiaiAoHjiAUwTyUxMPJVlqIBmWlia20I0t2ZmmikIbi00cJeiUoa6JbcaiSJ4ABRQBhju3x/+XF9HGAYPM6Dr/bqurst1zz1rfdawmves070UQggBIiKSLaOmLoCIiJoWg4CISOYYBEREMscgICKSOQYBEZHMMQiIiGSOQSBTq1atwuzZswEAFy9eRPfu3VFTU9PEVTXOO++8gxUrVgAAjh07Bl9f3yau6OHduy5PgobqjYmJwerVqw1cET0ODAID2rFjBwICAtCnTx/0798fCxYswM2bN5u6rCbn7e2NX3755aHe6+Ligr179z6WeT2MJ+2LXJ9iY2Px5ptvGnSZ4eHh2LZtW6P73/sDiP4fBoGBrF+/Hh999BHmzJmDY8eOYevWrSgoKMDEiRNRVVX1WJf1pPyyb+51Nvf6iB4XBoEBlJeXY9WqVZg/fz48PT1hamoKOzs7fPLJJygoKEBycjKKiorQu3dvlJaWSu/7z3/+A3d3d1RXVwMAtm/fjqFDh8LV1RWTJk3CpUuXpL7du3fH5s2bMXjwYAwePBgAEB8fDy8vL/Tt2xcjR47EsWPHHqp+b29vJCUlISAgAI6Ojnj33Xdx7do1REREwMnJCRMmTMCNGzek/unp6fDz84OLiwvCw8Nx7tw5jXklJiZK85o5cyYKCgowZcoUODk5Ye3atQCA6dOno3///nB2dkZoaCj++9//1ltbVlYWPD09AQBz5sypM6/IyEhs2rRJ4z0BAQH48ccf68zr7iGybdu24eWXX8arr77aYC1bt25FSkoK1q1bBycnJ0yZMgUAUFRUhKioKPTr1w/e3t7YuHFjg59vSUkJJk6cCCcnJ4SFhUl/10WLFmHp0qUafadMmYINGzbUmYcQAkuWLIGHhwecnZ0REBCAM2fOALiz17Jw4ULp7zVu3DhcvXoVixcvhqurK4YMGYL//Oc/0rzOnTuH8PBwuLi4wM/PD+np6fXWXV5ejvDwcMTHx0MIobF3dPfvsn79enh4eGDAgAH47rvvNNZ5ypQp6Nu3L4KDg7FixQqEhITUuxyVSoXZs2fD3d0dLi4uCA4OxrVr17BixQocO3YMsbGxcHJyQmxsLADt231mZia++OIL7NmzB05OThg+fDiAunuR9+41aFv2U0eQ3mVkZIgePXqI6urqOq/NnTtXREdHCyGECA8PF1u3bpVeW7p0qXj//feFEEL88MMPYtCgQeLs2bOiurparF69WowdO1bq261bNzFhwgRRUlIibt++LYQQYufOnaK4uFhUV1eLdevWib///e+isrJSCCHEypUrxaxZs4QQQuTn54tu3brVW58QQgwcOFCMHj1aXL16VRQWFop+/fqJoKAgcerUKaFSqUR4eLhYtWqVEEKI8+fPiz59+oh///vfoqqqSiQmJopBgwYJlUolzWv48OGioKBAqnPgwIHi559/1ljmtm3bRFlZmVCpVCI+Pl4MHz5ceu3tt98WCQkJQgghDh8+LF566SWNWu+dV2pqqhg1apQ0ffr0aeHm5ibVc6+7n8OcOXNERUWFVF9jaxFCCLVaLUaMGCFWrVolVCqVuHDhgvD29haZmZn1frZvv/22cHR0FEeOHBEqlUrExcWJcePGCSGE+P3330X//v2FWq0WQghx/fp10bt3b3H16tU688nMzBQjRowQN27cELW1teLs2bOiqKhIWoabm5s4ceKEqKysFOHh4WLgwIHi+++/FzU1NSIhIUGEhYUJIYSoqqoSgwYNEmvWrBEqlUr88ssvwtHRUZw7d05jfYuLi0VwcLDGut//d+nRo4f45JNPRFVVlfjpp59E7969RWlpqRBCiBkzZogZM2aIW7duif/+97/C09NTWu/7bdmyRbz++uvi1q1boqamRpw4cUKUlZUJIYQICwsT3377rUb/xm73d92/zdzbp6FlP024R2AAJSUlaNu2LUxMTOq89uyzz6KkpATAnV+qu3fvBnDnF15aWhoCAgIAAN988w0iIyPRpUsXmJiYYMqUKTh9+rTGXkFkZCTatGkDc3NzAEBgYKC03Ndeew1VVVX4888/H2odwsLC0KFDB9jY2MDFxQW9e/fG//7v/8LMzAw+Pj7SL8q0tDR4eXmhf//+MDU1xaRJk1BZWYnffvtNmld4eDhsbW2lOuszatQo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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Cell 4 — Bar plot with error bars (overall)\n",
+ "plt.figure(figsize=(6,4))\n",
+ "x = grouped.index.tolist()\n",
+ "rates = grouped['mortality_rate'].values\n",
+ "err_low = rates - grouped['ci_lower'].values\n",
+ "err_high = grouped['ci_upper'].values - rates\n",
+ "\n",
+ "plt.bar(x, rates, yerr=[err_low, err_high], capsize=6)\n",
+ "plt.ylim(0, 1)\n",
+ "plt.ylabel(\"Mortality rate (20 yr)\")\n",
+ "plt.title(\"Overall mortality rate by smoking status\\n(95% Wilson CI)\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ValueError",
+ "evalue": "Shape of passed values is (8, 2), indices imply (8, 4)",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mcreate_block_manager_from_arrays\u001b[0;34m(arrays, names, axes)\u001b[0m\n\u001b[1;32m 4637\u001b[0m \u001b[0mblocks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mform_blocks\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnames\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4638\u001b[0;31m \u001b[0mmgr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mBlockManager\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mblocks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4639\u001b[0m \u001b[0mmgr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_consolidate_inplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, blocks, axes, do_integrity_check, fastpath)\u001b[0m\n\u001b[1;32m 3032\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mdo_integrity_check\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3033\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_verify_integrity\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3034\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36m_verify_integrity\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 3243\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mblock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_verify_integrity\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mblock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mmgr_shape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3244\u001b[0;31m \u001b[0mconstruction_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtot_items\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mblock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3245\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mtot_items\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mconstruction_error\u001b[0;34m(tot_items, block_shape, axes, e)\u001b[0m\n\u001b[1;32m 4607\u001b[0m raise ValueError(\"Shape of passed values is {0}, indices imply {1}\".format(\n\u001b[0;32m-> 4608\u001b[0;31m passed, implied))\n\u001b[0m\u001b[1;32m 4609\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Shape of passed values is (8, 2), indices imply (8, 4)",
+ "\nDuring handling of the above exception, another exception occurred:\n",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;31m# add Wilson CI per group\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mcis_age\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0magg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mrow\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mproportion_confint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcount\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'dead'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnobs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'total'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'wilson'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0magg\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'ci_lower'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcis_age\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0magg\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'ci_upper'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcis_age\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, func, axis, broadcast, raw, reduce, args, **kwds)\u001b[0m\n\u001b[1;32m 4875\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4876\u001b[0m \u001b[0mreduce\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mreduce\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4877\u001b[0;31m ignore_failures=ignore_failures)\n\u001b[0m\u001b[1;32m 4878\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4879\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply_broadcast\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_apply_standard\u001b[0;34m(self, func, axis, ignore_failures, reduce)\u001b[0m\n\u001b[1;32m 4988\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4989\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4990\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_constructor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mresults\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4991\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mres_index\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4992\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data, index, columns, dtype, copy)\u001b[0m\n\u001b[1;32m 328\u001b[0m dtype=dtype, copy=copy)\n\u001b[1;32m 329\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 330\u001b[0;31m \u001b[0mmgr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_init_dict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 331\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMaskedArray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 332\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmrecords\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmrecords\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_init_dict\u001b[0;34m(self, data, index, columns, dtype)\u001b[0m\n\u001b[1;32m 459\u001b[0m \u001b[0marrays\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mkeys\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 460\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 461\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_arrays_to_mgr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata_names\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 462\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 463\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_init_ndarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_arrays_to_mgr\u001b[0;34m(arrays, arr_names, index, columns, dtype)\u001b[0m\n\u001b[1;32m 6171\u001b[0m \u001b[0maxes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0m_ensure_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_ensure_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6172\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 6173\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcreate_block_manager_from_arrays\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marr_names\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6174\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6175\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mcreate_block_manager_from_arrays\u001b[0;34m(arrays, names, axes)\u001b[0m\n\u001b[1;32m 4640\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmgr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4641\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mValueError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4642\u001b[0;31m \u001b[0mconstruction_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marrays\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4643\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4644\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mconstruction_error\u001b[0;34m(tot_items, block_shape, axes, e)\u001b[0m\n\u001b[1;32m 4606\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Empty data passed with indices specified.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4607\u001b[0m raise ValueError(\"Shape of passed values is {0}, indices imply {1}\".format(\n\u001b[0;32m-> 4608\u001b[0;31m passed, implied))\n\u001b[0m\u001b[1;32m 4609\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4610\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Shape of passed values is (8, 2), indices imply (8, 4)"
+ ]
+ }
+ ],
+ "source": [
+ "# Cell 5 — Step 2: Add age groups and compute mortality within each strata\n",
+ "bins = [18, 34, 54, 64, df['Age'].max()+1] # last bin includes max\n",
+ "labels = ['18-34','34-54','55-64','65+']\n",
+ "df['AgeGroup'] = pd.cut(df['Age'], bins=bins, labels=labels, right=True, include_lowest=True)\n",
+ "\n",
+ "# Group by age group and smoker\n",
+ "agg = df.groupby(['AgeGroup','Smoker'])['Death'].agg(['sum','count']).rename(columns={'sum':'dead','count':'total'})\n",
+ "agg['alive'] = agg['total'] - agg['dead']\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# add Wilson CI per group\n",
+ "cis_age = agg.apply(lambda row: proportion_confint(count=int(row['dead']), nobs=int(row['total']), alpha=0.05, method='wilson'), axis=1)\n",
+ "agg['ci_lower'] = [c[0] for c in cis_age]\n",
+ "agg['ci_upper'] = [c[1] for c in cis_age]\n",
+ "\n",
+ "print(\"Mortality by Age group and Smoker (with 95% CI):\")\n",
+ "agg[['alive','dead','total','mortality_rate','ci_lower','ci_upper']]\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "\n",
+ "# Example: your aggregated DataFrame (agg)\n",
+ "# Make sure these columns exist: 'dead', 'total'\n",
+ "# agg = pd.DataFrame(...)\n",
+ "\n",
+ "# Compute CIs as two separate lists\n",
+ "ci_lower = []\n",
+ "ci_upper = []\n",
+ "\n",
+ "for _, row in agg.iterrows():\n",
+ " low, up = proportion_confint(\n",
+ " count=int(row['dead']),\n",
+ " nobs=int(row['total']),\n",
+ " alpha=0.05,\n",
+ " method='wilson'\n",
+ " )\n",
+ " ci_lower.append(low)\n",
+ " ci_upper.append(up)\n",
+ "\n",
+ "# Add them to the DataFrame\n",
+ "agg['ci_lower'] = ci_lower\n",
+ "agg['ci_upper'] = ci_upper\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ValueError",
+ "evalue": "Shape of passed values is (8, 2), indices imply (8, 4)",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mcreate_block_manager_from_arrays\u001b[0;34m(arrays, names, axes)\u001b[0m\n\u001b[1;32m 4637\u001b[0m \u001b[0mblocks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mform_blocks\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnames\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4638\u001b[0;31m \u001b[0mmgr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mBlockManager\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mblocks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4639\u001b[0m \u001b[0mmgr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_consolidate_inplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, blocks, axes, do_integrity_check, fastpath)\u001b[0m\n\u001b[1;32m 3032\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mdo_integrity_check\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3033\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_verify_integrity\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3034\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36m_verify_integrity\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 3243\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mblock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_verify_integrity\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mblock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mmgr_shape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3244\u001b[0;31m \u001b[0mconstruction_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtot_items\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mblock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3245\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mtot_items\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mconstruction_error\u001b[0;34m(tot_items, block_shape, axes, e)\u001b[0m\n\u001b[1;32m 4607\u001b[0m raise ValueError(\"Shape of passed values is {0}, indices imply {1}\".format(\n\u001b[0;32m-> 4608\u001b[0;31m passed, implied))\n\u001b[0m\u001b[1;32m 4609\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Shape of passed values is (8, 2), indices imply (8, 4)",
+ "\nDuring handling of the above exception, another exception occurred:\n",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;31m# add Wilson CI per group\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mcis_age\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0magg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mrow\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mproportion_confint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcount\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'dead'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnobs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'total'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0.05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'wilson'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0magg\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'ci_lower'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcis_age\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0magg\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'ci_upper'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcis_age\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, func, axis, broadcast, raw, reduce, args, **kwds)\u001b[0m\n\u001b[1;32m 4875\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4876\u001b[0m \u001b[0mreduce\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mreduce\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4877\u001b[0;31m ignore_failures=ignore_failures)\n\u001b[0m\u001b[1;32m 4878\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4879\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply_broadcast\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_apply_standard\u001b[0;34m(self, func, axis, ignore_failures, reduce)\u001b[0m\n\u001b[1;32m 4988\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4989\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4990\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_constructor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mresults\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4991\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mres_index\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4992\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data, index, columns, dtype, copy)\u001b[0m\n\u001b[1;32m 328\u001b[0m dtype=dtype, copy=copy)\n\u001b[1;32m 329\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 330\u001b[0;31m \u001b[0mmgr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_init_dict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 331\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMaskedArray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 332\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmrecords\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmrecords\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_init_dict\u001b[0;34m(self, data, index, columns, dtype)\u001b[0m\n\u001b[1;32m 459\u001b[0m \u001b[0marrays\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mkeys\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 460\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 461\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_arrays_to_mgr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata_names\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 462\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 463\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_init_ndarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_arrays_to_mgr\u001b[0;34m(arrays, arr_names, index, columns, dtype)\u001b[0m\n\u001b[1;32m 6171\u001b[0m \u001b[0maxes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0m_ensure_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_ensure_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6172\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 6173\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcreate_block_manager_from_arrays\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marr_names\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6174\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6175\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mcreate_block_manager_from_arrays\u001b[0;34m(arrays, names, axes)\u001b[0m\n\u001b[1;32m 4640\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmgr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4641\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mValueError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4642\u001b[0;31m \u001b[0mconstruction_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marrays\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4643\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4644\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mconstruction_error\u001b[0;34m(tot_items, block_shape, axes, e)\u001b[0m\n\u001b[1;32m 4606\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Empty data passed with indices specified.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4607\u001b[0m raise ValueError(\"Shape of passed values is {0}, indices imply {1}\".format(\n\u001b[0;32m-> 4608\u001b[0;31m passed, implied))\n\u001b[0m\u001b[1;32m 4609\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4610\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mValueError\u001b[0m: Shape of passed values is (8, 2), indices imply (8, 4)"
+ ]
+ }
+ ],
+ "source": [
+ "# Cell 5 — Step 2: Add age groups and compute mortality within each strata\n",
+ "bins = [18, 34, 54, 64, df['Age'].max()+1] # last bin includes max\n",
+ "labels = ['18-34','34-54','55-64','65+']\n",
+ "df['AgeGroup'] = pd.cut(df['Age'], bins=bins, labels=labels, right=True, include_lowest=True)\n",
+ "\n",
+ "# Group by age group and smoker\n",
+ "agg = df.groupby(['AgeGroup','Smoker'])['Death'].agg(['sum','count']).rename(columns={'sum':'dead','count':'total'})\n",
+ "agg['alive'] = agg['total'] - agg['dead']\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# add Wilson CI per group\n",
+ "cis_age = agg.apply(lambda row: proportion_confint(count=int(row['dead']), nobs=int(row['total']), alpha=0.05, method='wilson'), axis=1)\n",
+ "agg['ci_lower'] = [c[0] for c in cis_age]\n",
+ "agg['ci_upper'] = [c[1] for c in cis_age]\n",
+ "\n",
+ "print(\"Mortality by Age group and Smoker (with 95% CI):\")\n",
+ "agg[['alive','dead','total','mortality_rate','ci_lower','ci_upper']]\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "aggregate() missing 1 required positional argument: 'arg'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 8\u001b[0m agg = df.groupby('Smoker').agg(\n\u001b[1;32m 9\u001b[0m \u001b[0malive\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Alive'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mdead\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Dead'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m ).reset_index()\n\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mTypeError\u001b[0m: aggregate() missing 1 required positional argument: 'arg'"
+ ]
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "\n",
+ "# Example: df is your main dataset\n",
+ "# Columns needed: 'Smoker' ('Yes'/'No'), 'Alive'/'Dead' status (or 'Death' 1/0)\n",
+ "\n",
+ "# Tabulate\n",
+ "agg = df.groupby('Smoker').agg(\n",
+ " alive=('Alive', 'sum'),\n",
+ " dead=('Dead', 'sum')\n",
+ ").reset_index()\n",
+ "\n",
+ "# Total per group\n",
+ "agg['total'] = agg['alive'] + agg['dead']\n",
+ "\n",
+ "# Mortality rate\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# Confidence intervals\n",
+ "ci_lower, ci_upper = [], []\n",
+ "for _, row in agg.iterrows():\n",
+ " low, up = proportion_confint(\n",
+ " count=int(row['dead']),\n",
+ " nobs=int(row['total']),\n",
+ " alpha=0.05,\n",
+ " method='wilson'\n",
+ " )\n",
+ " ci_lower.append(low)\n",
+ " ci_upper.append(up)\n",
+ "\n",
+ "agg['ci_lower'] = ci_lower\n",
+ "agg['ci_upper'] = ci_upper\n",
+ "\n",
+ "print(agg)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/opt/conda/lib/python3.6/site-packages/pandas/core/groupby.py:4291: FutureWarning: using a dict with renaming is deprecated and will be removed in a future version\n",
+ " return super(DataFrameGroupBy, self).aggregate(arg, *args, **kwargs)\n"
+ ]
+ },
+ {
+ "ename": "KeyError",
+ "evalue": "'Alive'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2524\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2525\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2526\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;31mKeyError\u001b[0m: 'Alive'",
+ "\nDuring handling of the above exception, another exception occurred:\n",
+ "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m agg = df.groupby('Smoker').agg({\n\u001b[1;32m 2\u001b[0m \u001b[0;34m'Alive'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;34m'Dead'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m }).reset_index()\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/groupby.py\u001b[0m in \u001b[0;36maggregate\u001b[0;34m(self, arg, *args, **kwargs)\u001b[0m\n\u001b[1;32m 4289\u001b[0m versionadded=''))\n\u001b[1;32m 4290\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0maggregate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4291\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mDataFrameGroupBy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maggregate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4292\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4293\u001b[0m \u001b[0magg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0maggregate\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/groupby.py\u001b[0m in \u001b[0;36maggregate\u001b[0;34m(self, arg, *args, **kwargs)\u001b[0m\n\u001b[1;32m 3722\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3723\u001b[0m \u001b[0m_level\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'_level'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3724\u001b[0;31m \u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhow\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_aggregate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_level\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0m_level\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3725\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhow\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3726\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/base.py\u001b[0m in \u001b[0;36m_aggregate\u001b[0;34m(self, arg, *args, **kwargs)\u001b[0m\n\u001b[1;32m 476\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 477\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 478\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_agg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_agg_1dim\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 479\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mSpecificationError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 480\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/base.py\u001b[0m in \u001b[0;36m_agg\u001b[0;34m(arg, func)\u001b[0m\n\u001b[1;32m 427\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompat\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOrderedDict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 428\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0magg_how\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcompat\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miteritems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 429\u001b[0;31m \u001b[0mresult\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mfname\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0magg_how\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 430\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 431\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/base.py\u001b[0m in \u001b[0;36m_agg_1dim\u001b[0;34m(name, how, subset)\u001b[0m\n\u001b[1;32m 406\u001b[0m \u001b[0maggregate\u001b[0m \u001b[0ma\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mdim\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mhow\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 407\u001b[0m \"\"\"\n\u001b[0;32m--> 408\u001b[0;31m \u001b[0mcolg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_gotitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mndim\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubset\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msubset\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 409\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcolg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 410\u001b[0m raise SpecificationError(\"nested dictionary is ambiguous \"\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/groupby.py\u001b[0m in \u001b[0;36m_gotitem\u001b[0;34m(self, key, ndim, subset)\u001b[0m\n\u001b[1;32m 4316\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mndim\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4317\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0msubset\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4318\u001b[0;31m \u001b[0msubset\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4319\u001b[0m return SeriesGroupBy(subset, selection=key,\n\u001b[1;32m 4320\u001b[0m grouper=self.grouper)\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2137\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2138\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2139\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_column\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2140\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2141\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_getitem_column\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_getitem_column\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2144\u001b[0m \u001b[0;31m# get column\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2145\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_unique\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2146\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_item_cache\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2147\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2148\u001b[0m \u001b[0;31m# duplicate columns & possible reduce dimensionality\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m_get_item_cache\u001b[0;34m(self, item)\u001b[0m\n\u001b[1;32m 1840\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcache\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1841\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mres\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1842\u001b[0;31m \u001b[0mvalues\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1843\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_box_item_values\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1844\u001b[0m \u001b[0mcache\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, item, fastpath)\u001b[0m\n\u001b[1;32m 3841\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3842\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3843\u001b[0;31m \u001b[0mloc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3844\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3845\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2525\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2526\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2527\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_maybe_cast_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2528\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2529\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtolerance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtolerance\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;31mKeyError\u001b[0m: 'Alive'"
+ ]
+ }
+ ],
+ "source": [
+ "agg = df.groupby('Smoker').agg({\n",
+ " 'Alive': 'sum',\n",
+ " 'Dead': 'sum'\n",
+ "}).reset_index()\n",
+ "\n",
+ "# Total per group\n",
+ "agg['total'] = agg['Alive'] + agg['Dead']\n",
+ "\n",
+ "# Mortality rate\n",
+ "agg['mortality_rate'] = agg['Dead'] / agg['total']\n",
+ "\n",
+ "# Confidence intervals\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "\n",
+ "ci_lower, ci_upper = [], []\n",
+ "for _, row in agg.iterrows():\n",
+ " low, up = proportion_confint(\n",
+ " count=int(row['Dead']),\n",
+ " nobs=int(row['total']),\n",
+ " alpha=0.05,\n",
+ " method='wilson'\n",
+ " )\n",
+ " ci_lower.append(low)\n",
+ " ci_upper.append(up)\n",
+ "\n",
+ "agg['ci_lower'] = ci_lower\n",
+ "agg['ci_upper'] = ci_upper\n",
+ "\n",
+ "print(agg)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Status Smoker alive dead total mortality_rate ci_lower ci_upper\n",
+ "0 No 502 230 732 0.314208 0.281624 0.348731\n",
+ "1 Yes 443 139 582 0.238832 0.205976 0.275112\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Count alive and dead per smoking group\n",
+ "agg = df.groupby(['Smoker', 'Status']).size().unstack(fill_value=0).reset_index()\n",
+ "\n",
+ "# Rename columns for clarity\n",
+ "agg = agg.rename(columns={'Alive': 'alive', 'Dead': 'dead'})\n",
+ "\n",
+ "# Total and mortality rate\n",
+ "agg['total'] = agg['alive'] + agg['dead']\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# Confidence intervals\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "ci_lower, ci_upper = [], []\n",
+ "\n",
+ "for _, row in agg.iterrows():\n",
+ " low, up = proportion_confint(\n",
+ " count=int(row['dead']),\n",
+ " nobs=int(row['total']),\n",
+ " alpha=0.05,\n",
+ " method='wilson'\n",
+ " )\n",
+ " ci_lower.append(low)\n",
+ " ci_upper.append(up)\n",
+ "\n",
+ "agg['ci_lower'] = ci_lower\n",
+ "agg['ci_upper'] = ci_upper\n",
+ "\n",
+ "print(agg)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "aggregate() missing 1 required positional argument: 'arg'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 14\u001b[0m agg = df.groupby('Smoker').agg(\n\u001b[1;32m 15\u001b[0m \u001b[0malive\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'alive'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 16\u001b[0;31m \u001b[0mdead\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'dead'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 17\u001b[0m ).reset_index()\n\u001b[1;32m 18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mTypeError\u001b[0m: aggregate() missing 1 required positional argument: 'arg'"
+ ]
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from scipy.stats import norm\n",
+ "import statsmodels.api as sm\n",
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "# --- 1. Mortality by Smoking Status ---\n",
+ "\n",
+ "# Create Alive/Dead counts if not already present\n",
+ "df['alive'] = (df['Status'] == 'Alive').astype(int)\n",
+ "df['dead'] = (df['Status'] == 'Dead').astype(int)\n",
+ "\n",
+ "agg = df.groupby('Smoker').agg(\n",
+ " alive=('alive', 'sum'),\n",
+ " dead=('dead', 'sum')\n",
+ ").reset_index()\n",
+ "\n",
+ "agg['total'] = agg['alive'] + agg['dead']\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# 95% confidence intervals (normal approx)\n",
+ "z = norm.ppf(0.975)\n",
+ "agg['ci_lower'] = agg['mortality_rate'] - z * np.sqrt(\n",
+ " agg['mortality_rate'] * (1 - agg['mortality_rate']) / agg['total']\n",
+ ")\n",
+ "agg['ci_upper'] = agg['mortality_rate'] + z * np.sqrt(\n",
+ " agg['mortality_rate'] * (1 - agg['mortality_rate']) / agg['total']\n",
+ ")\n",
+ "\n",
+ "print(\"\\nMortality by Smoking Status:\")\n",
+ "print(agg)\n",
+ "\n",
+ "sns.barplot(\n",
+ " data=agg,\n",
+ " x='Smoker', y='mortality_rate', \n",
+ " yerr=[agg['mortality_rate'] - agg['ci_lower'], agg['ci_upper'] - agg['mortality_rate']]\n",
+ ")\n",
+ "plt.ylabel('Mortality Rate')\n",
+ "plt.title('Mortality Rate by Smoking Status with 95% CI')\n",
+ "plt.show()\n",
+ "\n",
+ "# --- 2. Mortality by Smoking Status & Age Group ---\n",
+ "\n",
+ "# Create age groups\n",
+ "bins = [18, 34, 54, 64, np.inf]\n",
+ "labels = ['18-34', '35-54', '55-64', '65+']\n",
+ "df['age_group'] = pd.cut(df['Age'], bins=bins, labels=labels, right=True)\n",
+ "\n",
+ "agg_age = df.groupby(['age_group', 'Smoker']).agg(\n",
+ " alive=('alive', 'sum'),\n",
+ " dead=('dead', 'sum')\n",
+ ").reset_index()\n",
+ "\n",
+ "agg_age['total'] = agg_age['alive'] + agg_age['dead']\n",
+ "agg_age['mortality_rate'] = agg_age['dead'] / agg_age['total']\n",
+ "\n",
+ "print(\"\\nMortality by Smoking Status & Age Group:\")\n",
+ "print(agg_age)\n",
+ "\n",
+ "sns.catplot(\n",
+ " data=agg_age, kind='bar',\n",
+ " x='age_group', y='mortality_rate', hue='Smoker'\n",
+ ")\n",
+ "plt.ylabel('Mortality Rate')\n",
+ "plt.title('Mortality Rate by Smoking Status and Age Group')\n",
+ "plt.show()\n",
+ "\n",
+ "# --- 3. Logistic Regression ---\n",
+ "\n",
+ "df['Death'] = (df['Status'] == 'Dead').astype(int)\n",
+ "\n",
+ "X = df[['Age']]\n",
+ "X['Smoker'] = (df['Smoker'] == 'Yes').astype(int)\n",
+ "X = sm.add_constant(X)\n",
+ "y = df['Death']\n",
+ "\n",
+ "model = sm.Logit(y, X).fit()\n",
+ "print(model.summary())\n",
+ "\n",
+ "# Predict for plotting\n",
+ "age_range = np.linspace(df['Age'].min(), df['Age'].max(), 100)\n",
+ "pred_df = pd.DataFrame({\n",
+ " 'const': 1,\n",
+ " 'Age': np.tile(age_range, 2),\n",
+ " 'Smoker': np.repeat([0, 1], len(age_range))\n",
+ "})\n",
+ "pred_df['pred'] = model.predict(pred_df)\n",
+ "\n",
+ "sns.lineplot(\n",
+ " data=pred_df, x='Age', y='pred', hue='Smoker'\n",
+ ")\n",
+ "plt.ylabel('Predicted Probability of Death')\n",
+ "plt.title('Logistic Regression: Death ~ Age + Smoker')\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Smoker alive dead total mortality_rate ci_lower ci_upper\n",
+ "0 No 502 230 732 0.314208 0.280580 0.347835\n",
+ "1 Yes 443 139 582 0.238832 0.204192 0.273471\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEWCAYAAAB8LwAVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3XtUE2feB/BvICIq1ttK4gWpVtRuwYKg1suSbWrWCyhoVMxaukUp1lW68qrtqi0qimu1vrZrdb1Aqb3RrtYLCtYqrYRqvaFuXFvq5YiiLlG5rCIKGOb9w+O8RiYkKEMofj/neE5m5nkmv4GRb54nyYxCEAQBRERED3FxdgFERNQwMSCIiEgSA4KIiCQxIIiISBIDgoiIJDEgiIhIEgOCZHXp0iX07NkTd+/eBQBER0dj69atTq6qbmi1Whw4cMDZZdRKZGQkNm3aJLmtMf1uqG4wIBoprVYLX19fFBUVWa0PCwtDz549cenSpUfa75YtW2AwGB65rqSkJIwePbpO9vXXv/4Vvr6+CAgIQL9+/RAVFYVz58453L8h/YFfu3YttFotAgICEBwcjBkzZtR7DQ/+bupaTcdXU2hJWbVqFWbNmiVHmfQQBkQj1qlTJ6Snp4vLv/zyC+7cufPI+7s/CmhIJk+ejOPHj8NoNEKlUmHevHnOLqnWtm7diu3bt+Pjjz/G8ePH8fXXX2PAgAHOLqvONPbja8wYEI1YWFgYtm3bJi5v27YN4eHhVm1u3ryJN998Ey+88AJefPFFrFmzBlVVVQDuvcKfMGEClixZgn79+iEuLg7z58/HiRMnEBAQgKCgIADAvn37EB4ejj59+kCj0WDVqlU2a7r/avHcuXPV9mUymTBw4ECrINq9ezfCwsLsHqu7uzuGDx+O3Nxccd3FixfxyiuvoH///ujfvz9mzpyJGzduAABmz56NK1eu4PXXX0dAQAA2bNgAADhx4gQmTJiAoKAgjBo1CocOHarxeU+ePIkRI0agb9++mDNnDsrLywEAoaGh+O6778R2lZWV6N+/P37++WfJfQwePBhdunQBALRv3x4RERFWP7OVK1diwoQJCAgIwOuvv47i4mLMnDkTffr0gV6vtxoRHjt2DHq9HoGBgdDr9Th27Jhk7VevXsXIkSORnJwsPs/9V/L3R3fvvvsu+vbtC61Wi6ysLLFvfn4+Jk6ciICAALz66qtYuHChzVf1NR3fypUrcfToUSQkJCAgIAAJCQkAgMWLF0Oj0aBPnz4YM2YMjh49CgAwGo1Yt24ddu3ahYCAAIwaNQpA9dHgg6OM8vJyzJo1C/3790dQUBD0ej2uX78uWStZY0A0Yv7+/igtLcW5c+dgsViQkZEh/oe6b9GiRbh58yb27t2LTz/9FNu3b8fXX38tbjeZTPDy8sKBAwewfPlyLFy4EP7+/jh+/Lj4n7ZZs2Z49913cfToUaxbtw6pqanYu3dvjbU988wz1fbVu3dvtG7dGvv37xfbpaWlORQQZWVl2Llzp/hHCAAEQcCUKVOQnZ2NXbt2oaCgQAyv5cuXo2PHjli7di2OHz+O1157DWazGVOmTMHUqVNx+PBhvPXWW3jjjTeqTdM9aMeOHUhOTsaePXtw/vx5rFmzBsC9cE5LSxPbZWVlwdPTE88++2y1fTz//PPYvn07kpKScPLkSVgslmptMjIysGzZMhiNRly8eBETJkyAXq/H4cOH8cwzz2D16tUAgJKSEkyZMgWRkZE4dOgQoqKiMGXKFBQXF1vt79KlS4iMjMTLL7+MyZMnSx6byWRC165dcfDgQURHR2PevHm4f2WeWbNmoXfv3jh06BCmT5+O7du32/wZ1XR8cXFxCAoKQnx8PI4fP474+HgAgJ+fH7Zt24bDhw8jNDQUf/nLX1BeXo7g4GBMmTIFw4cPx/Hjx61+xrZs3boVpaWl2LdvHw4dOoSFCxfC3d3dbj9iQDR690cR+/fvR7du3aBSqcRt90Nj5syZ8PDwQOfOnREVFWX1n87T0xORkZFQKpU2/1P1798fPXv2hIuLC3r16oWQkBAcPnz4keoNDw8Xn7+kpAQ//PADQkNDbbb/6KOPEBQUhD59+iAnJwfLli0Tt3l7e2PQoEFwc3ND27ZtERUVhSNHjtjc1/bt2xEcHAyNRgMXFxcMGjQIvr6+Vq+cHzZx4kR06NABrVu3xtSpU8UpvVGjRiErKwulpaUA7gXdw+F8X1hYGN5++2388MMPiIyMxMCBA7F+/XqrNmPGjEGXLl3QsmVLBAcHw8vLCwMHDoRSqcSwYcPw008/Abg3mvP29kZ4eDiUSiVCQ0PRrVs3fP/99+K+zp49i1deeQWxsbFWI5WHdezYEePHj4erqytGjx6Na9eu4fr167hy5QpOnjyJN954A25ubggKCoJWq7W5H0eOT6pPmzZtoFQqMWnSJFRUVOD8+fM19rFFqVSipKQEFy5cgKurK3x9feHh4fFI+3rSKJ1dAMkrLCwML7/8Mi5dulTtlXhxcTEqKyvRsWNHcV3Hjh1hNpvFZbVabfc5/vWvf+G9997DmTNnUFlZiYqKCgwbNuyR6x0+fDhu3bqFXbt2ISgoCJ6enjbbT5o0CXFxcbhy5Qqio6Nx/vx59OrVCwBQWFiIxYsX4+jRo7h16xYEQcBTTz1lc19XrlzBN998Y/XH9O7du+jfv7/NPh06dBAfd+zYEVevXgUAqFQq9OnTB7t374ZOp4PRaKzx/ZFRo0Zh1KhRqKysxN69ezF79mw8++yz+N3vfgcA+M1vfiO2bdq0qdWyu7s7ysrKANybNnrw93m/rgd/pzt27ECXLl0wdOhQm/U8/JzNmjUDcG+kVlxcjFatWonr7v8c/vOf/zzy8T3so48+wqZNm3D16lUoFAqUlpZWGwU5KiwsDAUFBfif//kf3LhxA6NGjUJcXByaNGnySPt7knAE0ch16tQJnTt3RlZWFv7whz9YbWvTpg2aNGmCK1euiOv+85//WI0yFAqFVZ+HlwFg5syZeOmll5CVlYWcnBxMmDABjlwkWGpfKpUKAQEB2LNnD7Zv327zVffDOnbsiHnz5iExMVF8I37FihVQKBRIS0vDsWPHsHz58hrr6tChA8LCwnD06FHx34kTJxATE2Ozz4N/FK9cuWIVZqNHj0ZaWhq++eYb+Pv7W/1cbWnSpAmGDx+OHj164MyZM44cuhVPT0+r3+f9Gh987unTp6NNmzaYOXOm5HSWPe3bt8d///tf3L592+o5HOHI8R09ehQbNmzA+++/jyNHjuDo0aNo2bKl+LuTOm+aNWtmVc+1a9esnnP69OnIyMjAl19+iX379lm9N0e2MSCeAImJidi4cSOaN29utd7V1RXDhg3DypUrUVpaisuXLyMlJaXGP8rt2rWD2WxGRUWFuO7WrVto1aoVmjZtCpPJhJ07dzpUl9S+gHuv+JKTk3H69GnodDqHj3PQoEHw9PTEV199JdbVvHlzPPXUUzCbzUhKSrJq/5vf/Ab5+fni8qhRo/D9998jOzsbFosF5eXlOHToEAoKCmw+5xdffIGCggKUlJRg3bp1GDFihLhtyJAh+Omnn/DJJ59U+3DAg7Zs2YJ9+/ahtLQUVVVVyMrKwtmzZ9G7d2+Hj/0+jUaDvLw87NixA3fv3kVGRgbOnj2L3//+92KbJk2a4IMPPsDt27fx5ptvih9KcFSnTp3g6+uLVatWoaKiAsePH7caddX2+B7+Pdy6dQuurq5o27Yt7t69iw8//FCcqgPunTeXL1+2qrtXr17IyMhAZWUlTp48id27d4vbDh48iF9++QUWiwUeHh5QKpVwdXWt1TE/qRgQT4AuXbrAz89Pcts777yDZs2aYciQIfjjH/+I0NBQ6PV6m/t64YUX0L17dwwePFicepk/fz7+/ve/IyAgAKtXr8bw4cMdqktqXwCg0+lw+fJl6HS6aqFmT3R0NJKSklBRUYHp06fjp59+QlBQEGJiYqqNoGJiYvCPf/wDQUFBSE5ORocOHbBmzRqsW7cOAwYMgEajQXJyco1/QENDQzFp0iQMGTIEXl5emDp1qrjN3d0df/jDH3Dp0qUag87DwwNr167Fiy++iKCgILz33ntYsGCB+Cmx2mjTpg3Wrl2LlJQU9O/fH0lJSVi7di3atm1r1c7NzQ0ffvghCgsLMXfu3FqHxHvvvYcTJ06gf//+eP/99zFixAi4ubk90vG98sor2L17N/r27YvFixdj8ODBCA4OxtChQ6HVatG0aVOrqbz705f9+/cXv7cxY8YMXLx4Ef369cOqVaswcuRIsf3169fxxhtvIDAwECNGjEC/fv0cHpk+6RS8YRA1REOGDEFCQgIGDhzo7FIey4cffoi8vDy89957zi5FVjNmzEC3bt3wxhtvOLsUqkMcQVCDs3v3bigUCrzwwgvOLuWxlJSU4Ouvv67xk0K/ViaTCRcvXkRVVRWMRiMyMzMxZMgQZ5dFdYyfYqIGJTIyEmfPnsWyZcvg4vLrff3yz3/+E0uWLMGoUaPQt29fZ5dT565fv47Y2FiUlJRArVZjwYIF+O1vf+vssqiOcYqJiIgk/XpfohERkawa1RRTTk6Os0sgIvrVCQwMlFzfqAICsH2gRERUXU0vrDnFREREkhgQREQkiQFBRESSGBBERCRJ1jepjUYjEhMTUVVVhXHjxlW7KubevXvxwQcfwMXFBa6urpg7d654fRatVosWLVqI27Zs2SJnqURE9BDZAsJisSAhIQEpKSlQqVQYO3YstFotunfvLrYZMGAAXnrpJSgUCuTm5mLGjBn45ptvxO0bN26sdpExIiKqH7JNMZlMJnh7e8PLywtubm4ICQlBZmamVZsWLVqI13a/ffu25HXeiYjIOWQbQZjNZqu7kalUKphMpmrt9uzZgxUrVqCoqAjr1q2z2jZ58mQoFApEREQ4fMEzflmOiKhuyBYQUpd4khoh6HQ66HQ6HDlyBB988AE+/vhjAEBqaipUKhUKCwsRFRWFbt26OXTRM35RjojIcU75opxarba6E5fZbK7x3sJ9+/bFxYsXUVRUBADiLRLbtWsHnU4nOfogeTz99NN4+umnnV0GETmZbAHh5+eHvLw85Ofno6KiAunp6dBqtVZtLly4II40Tp06hcrKSrRp0wZlZWXiLQbLysqwf/9++Pj4yFUqERFJkG2KSalUIj4+HtHR0bBYLNDr9fDx8UFqaioAwGAwYPfu3di+fTuUSiXc3d2xcuVKKBQKFBYWYtq0aQDufRoqNDQUwcHBcpVKREQSGtX9IHJycvgeRB24P72Ul5fn1DqISH41/d3kN6mJiEgSA4KIiCQxIIiISBIDgoiIJDEgiIhIEgOCiIgkMSCIiEgSA4KIiCQxIIiISBIDgoiIJDEgiIhIEgOCiIgkMSCIiEgSA4KIiCQxIIiISBIDgoiIJMl2R7lfoz+++bmzS2gQrhffAsCfx31fLJvo7BKInIIjCCIiksSAICIiSQwIIiKSxIAgIiJJsgaE0WjE0KFDodPpsH79+mrb9+7di5EjRyIsLAxjxozB0aNHHe5LRETyku1TTBaLBQkJCUhJSYFKpcLYsWOh1WrRvXt3sc2AAQPw0ksvQaFQIDc3FzNmzMA333zjUF8iIpKXbCMIk8kEb29veHl5wc3NDSEhIcjMzLRq06JFCygUCgDA7du3xceO9CUiInnJNoIwm81Qq9XiskqlgslkqtZuz549WLFiBYqKirBu3bpa9ZWSk5PzmJUTWeM5RU8q2QJCEIRq6+6PEB6k0+mg0+lw5MgRfPDBB/j4448d7islMDCw9sXe91Xuo/elRuuxzimiBq6mF0CyTTGp1WoUFBSIy2azGZ6enjbb9+3bFxcvXkRRUVGt+xIRUd2TLSD8/PyQl5eH/Px8VFRUID09HVqt1qrNhQsXxNHCqVOnUFlZiTZt2jjUl4iI5CXbFJNSqUR8fDyio6NhsVig1+vh4+OD1NRUAIDBYMDu3buxfft2KJVKuLu7Y+XKlVAoFDb7EhFR/ZH1Yn0ajQYajcZqncFgEB/HxMQgJibG4b5ERFR/+E1qIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIiksSAICIiSbwnNVUzasr7zi6BiBoAjiCIiEgSA4KIiCQxIIiISBIDgoh+VZ5++mk8/fTTzi7jicCAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIiksSAICIiSQwIIiKSxIAgIiJJDAgiIpIk6+W+jUYjEhMTUVVVhXHjxiEmJsZqe1paGjZs2AAAaNGiBRYsWIBevXoBALRaLVq0aAEXFxe4urpiy5YtcpZKREQPkS0gLBYLEhISkJKSApVKhbFjx0Kr1aJ79+5im86dO+Ozzz5Dq1atkJWVhXfeeQebNm0St2/cuBFt27aVq0QiIqqBbFNMJpMJ3t7e8PLygpubG0JCQpCZmWnVpk+fPmjVqhUAwN/fHwUFBXKVQ0REtSTbCMJsNkOtVovLKpUKJpPJZvvNmzcjODjYat3kyZOhUCgQERGBiIgIh543Jyfn0QomsoHnVMNSUVEBgL+X+iBbQAiCUG2dQqGQbHvw4EFs3rwZX3zxhbguNTUVKpUKhYWFiIqKQrdu3dC3b1+7zxsYGPjoRX+V++h9qdF6rHOK6pybmxsA/l7qSk1BK9sUk1qttpoyMpvN8PT0rNYuNzcXb7/9NtasWYM2bdqI61UqFQCgXbt20Ol0NY4+iIio7tkNCEEQsGnTJixfvhwAcOnSJRw7dszujv38/JCXl4f8/HxUVFQgPT0dWq3Wqs2VK1cQGxuLZcuWoWvXruL6srIylJaWio/3798PHx+fWh0YERE9HrtTTH/7299QWFiIU6dOYfbs2WjRogWWLFmCzZs317xjpRLx8fGIjo6GxWKBXq+Hj48PUlNTAQAGgwGrV69GSUkJFi5cCADix1kLCwsxbdo0APc+DRUaGlrt/QkiIpKX3YA4dOgQtm3bhtGjRwMA2rRpg/Lycod2rtFooNForNYZDAbxcWJiIhITE6v18/LyQlpamkPPQURE8rA7xdS0aVOrN5erqqpkLYiIiBoGuyOIHj16IC0tDYIg4NKlS1i/fj0/PUDkBK+m/MXZJTQI10uLAPDncd/HUR/Itm+7I4i//vWvOHz4MK5du4bx48ejqqoKs2fPlq0gIiJqGBz6HsTixYutlu9/woiIiBovuyOIyMhIh9YREVHjYnMEcffuXVRWVqKqqgp37twRvxl98+ZN3L59u94KJCIi57AZEGvXrsWHH34IhUIBf39/cb2HhweioqLqpTgiInIemwExffp0TJ8+HQkJCYiPj6/PmoiIqAGw+x4Ew4GI6Mlk91NMubm5mD9/PnJzc8XL7ALAzz//LGthRETkXHZHEAsWLMCMGTPg7e2NrKwsxMTEIC4urj5qIyIiJ7IbEBUVFRgwYAAEQYCnpyfi4uKQnZ1dH7UREZET2Q0IV1dXAECrVq2Qm5uL4uJiXL58WfbCiIjIuey+BzFixAgUFxcjJiYGBoMBVVVViI2NrY/aiIjIiewGxP3vPAQHB+Pw4cMoLy+Hh4eH7IUREZFz1eqWo02aNMGlS5c4giAiegLYDIjz58/jtddew8iRI7F27VrcuHEDcXFxePnll/Hss8/WZ41EROQENqeY4uPj8fzzzyMyMhKZmZmYMGECnnnmGezevRvt2rWrzxqJiMgJbAZESUkJZs2aBQAYPHgwBg0ahJUrV0KpdOgK4URE9Ctnc4rpwSBwcXGBWq1mOBARPUFs/sU/f/48xo4da3N58+bN8lZGREROZTMg1q9f/9g7NxqNSExMRFVVFcaNG4eYmBir7WlpadiwYQMAoEWLFliwYAF69erlUF8iejKNXc7bDdQXmwHRr1+/x9qxxWJBQkICUlJSoFKpMHbsWGi1WnTv3l1s07lzZ3z22Wdo1aoVsrKy8M4772DTpk0O9SUiInnV6nsQtWEymeDt7Q0vLy+4ubkhJCQEmZmZVm369OmDVq1aAQD8/f1RUFDgcF8iIpKXbO86m81mqNVqcVmlUsFkMtlsv3nzZgQHBz9S3wfl5OQ8YsVE0nhOUUMm5/kpW0Dcv4f1gxQKhWTbgwcPYvPmzfjiiy9q3fdhgYGBtajyIV/lPnpfarQe65yqS6ZPnF0BNUCPe37WFDAO3VHu9OnTtX5StVotThkB90YFnp6e1drl5ubi7bffxpo1a9CmTZta9SUiIvnYDYiuXbsiNjYWEydOREZGBu7evevQjv38/JCXl4f8/HxUVFQgPT0dWq3Wqs2VK1cQGxuLZcuWoWvXrrXqS0RE8nLoaq5RUVEwGo344osvsHTpUowdOxYRERFQqVS2d6xUIj4+HtHR0bBYLNDr9fDx8UFqaioAwGAwYPXq1SgpKcHChQsB3Lv3xJYtW2z2JSKi+uPwexD+/v44d+4ccnNzceLECWzevBmTJk3Cq6++arOPRqOBRqOxWmcwGMTHiYmJSExMdLgvERHVH7sB8e9//xuff/459u/fj9DQUHz22Wfo3LkzSktLERoaWmNAEBHRr5fdgJgzZw5efvllzJ8/H+7u7uJ6Dw8PvP7667IWR0REzmP3Teq5c+ciIiLCKhx+/PFHAMCECRPkq4yIiJzKbkAsW7as2rrly5fLUgwRETUcNqeYLly4gLy8PJSWliIrK0tcf/PmTdy+fbteiiMiIuexGRDHjh3Dli1bcP36dSQlJYnrPTw88NZbb9VLcURE5Dw2A2L06NEYPXo0tmzZgjFjxtRnTURE1ADYDIj8/Hx4eXmhd+/eOHv2bLXtvPQ2EVHjZjMgFi9ejHXr1kneqEehUPDy20REjZzNgFi3bh0A4Lvvvqu3YoiIqOGwGRD2PqnUrFmzOi+GiIgaDpsBERAQAIVCYfPeDD///LOshRERkXPZDIjcXN48h4joSSbbPamJiOjXze7F+nJzczF//nzk5uaioqJCXM8pJiKixs3uCGLBggWYMWMGvL29kZWVhZiYGMTFxdVHbURE5ER2A6KiogIDBgyAIAjw9PREXFwcsrOz66M2IiJyIrsB4erqCgBo1aoVcnNzUVxcjMuXL8teGBEROZfd9yBGjBiB4uJixMTEwGAwoKqqCrGxsfVRGxEROZHdgIiKigIABAcH4/DhwygvL4eHh4fshRERkXPZnWIyGAzi4yZNmsDDw8NqXU2MRiOGDh0KnU6H9evXV9t+7tw5REREwNfXF8nJyVbbtFotRo4cibCwMF5NlojICeyOIO7cuWO1bLFY8N///tfuji0WCxISEpCSkgKVSoWxY8dCq9VaXQW2devWmDdvns0L/23cuBFt27a1+1xERFT3bAZEUlISkpKSUFpaigEDBojr79y5g5EjR9rdsclkgre3N7y8vAAAISEhyMzMtAqIdu3aoV27dlZ3rCMioobBZkBERERg2LBhWLRoEeLj48X1Hh4eaNWqld0dm81mqNVqcVmlUsFkMtWquMmTJ0OhUCAiIgIREREO9cnJyanVcxDZw3OKGjI5z0+bAdGyZUs0b94cCoUCnTp1qvWObV3kz1GpqalQqVQoLCxEVFQUunXrhr59+9rtFxgYWKs6rXzF609RdY91TtUl0yfOroAaoMc9P2sKmBrfpHZ1dcWdO3dQVVVV6ydVq9UoKCgQl81mMzw9PR3ur1KpANybhtLpdLUefRAR0eOx+ymm559/HtOnT0dGRgaysrLEf/b4+fkhLy8P+fn5qKioQHp6OrRarUNFlZWVobS0VHy8f/9++Pj4ONSXiIjqht1PMR07dgzAvSmf+xQKBTQaTc07VioRHx+P6OhoWCwW6PV6+Pj4iPsxGAy4du0a9Ho9SktL4eLigo0bNyIjIwPFxcWYNm0agHufhgoNDUVwcPAjHyQREdWe3YD49NNPH3nnGo2mWpA8+B2K9u3bw2g0Vuvn4eGBtLS0R35eIiJ6fHYDAgCys7Nx4MABKBQKDBo0CIMGDZK7LiIicjK770Fs2LAB7777Lp566im0bNkSS5curfatZyIianzsjiDS0tLw5ZdfitdfioyMhMFgwOTJk2UvjoiInMehW44+eHE+XqiPiOjJYHcE4evrizlz5mDcuHFQKBTYtGkTfH1966M2IiJyIrsB8c4772D16tVYvHgxAGDgwIH485//LHthRETkXHYDonnz5pg9e3Z91EJERA2IzYD4/PPPa+w4ceLEOi+GiIgaDpsBsWjRIvj6+vISF0RETyibAZGYmIht27bh7NmzCA8PR2hoqEOX+SYiosbBZkDo9Xro9XpcunQJW7duhcFgQI8ePTB16lT07NmzPmskIiInsPs9iM6dO+PVV19FZGQkDh06xMtuExE9IWyOIARBQHZ2NrZs2YLTp09j+PDh+Oc//yneQpSIiBo3mwERHByM9u3bY8yYMZg2bRoUCgXKy8tx9uxZALC6tzQRETU+NgOiSZMmKCkpwUcffYSUlBSrW4gqFApkZmbWS4FEROQcNgPiu+++q886iIiogXHoYn1ERPTkYUAQEZEkBgQREUliQBARkSQGBBERSZI1IIxGI4YOHQqdTof169dX237u3DlERETA19e32n2u7fUlIiJ5yRYQFosFCQkJSEpKQnp6Onbu3Cl+ye6+1q1bY968edXub+1IXyIikpdsAWEymeDt7Q0vLy+4ubkhJCSk2pfr2rVrh969e0OpVNa6LxERycvuHeUeldlshlqtFpdVKpXDF/p7nL45OTm1K5TIDp5T1JDJeX7KFhAPXprjPoVCIXvfwMBAh9pJ+ir30ftSo/VY51RdMn3i7AqoAXrc87OmgJFtikmtVqOgoEBcNpvN8PT0lL0vERHVDdkCws/PD3l5ecjPz0dFRQXS09Oh1Wpl70tERHVDtikmpVKJ+Ph4REdHw2KxQK/Xw8fHB6mpqQAAg8GAa9euQa/Xo7S0FC4uLti4cSMyMjLg4eEh2ZeIiOqPbAEBABqNBhqNxmqdwWAQH7dv3x5Go9HhvkREVH/4TWoiIpLEgCAiIkkMCCIiksSAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIiksSAICIiSQwIIiKSxIAgIiJJDAgiIpINg8EnAAAJ4klEQVTEgCAiIkkMCCIiksSAICIiSQwIIiKSxIAgIiJJDAgiIpLEgCAiIkkMCCIikqSUc+dGoxGJiYmoqqrCuHHjEBMTY7VdEAQkJiYiKysL7u7uWLp0KZ577jkAgFarRYsWLeDi4gJXV1ds2bJFzlKJiOghsgWExWJBQkICUlJSoFKpMHbsWGi1WnTv3l1sYzQakZeXh2+//Rb/+te/sGDBAmzatEncvnHjRrRt21auEomIqAayTTGZTCZ4e3vDy8sLbm5uCAkJQWZmplWbzMxMhIeHQ6FQwN/fHzdu3MDVq1flKomIiGpBthGE2WyGWq0Wl1UqFUwmU41t1Go1zGYzPD09AQCTJ0+GQqFAREQEIiIiHHrenJycOqie6P/xnKKGTM7zU7aAEASh2jqFQuFwm9TUVKhUKhQWFiIqKgrdunVD37597T5vYGDgI1YM4KvcR+9LjdZjnVN1yfSJsyugBuhxz8+aAka2KSa1Wo2CggJx+cGRga02BQUFYhuVSgUAaNeuHXQ6XbXRBxERyUu2gPDz80NeXh7y8/NRUVGB9PR0aLVaqzZarRbbtm2DIAg4ceIEWrZsCU9PT5SVlaG0tBQAUFZWhv3798PHx0euUomISIJsU0xKpRLx8fGIjo6GxWKBXq+Hj48PUlNTAQAGgwEajQZZWVnQ6XRo1qwZlixZAgAoLCzEtGnTANz7NFRoaCiCg4PlKpWIiCTI+j0IjUYDjUZjtc5gMIiPFQoF5s+fX62fl5cX0tLS5CyNiIjs4DepiYhIEgOCiIgkMSCIiEgSA4KIiCQxIIiISBIDgoiIJDEgiIhIEgOCiIgkMSCIiEgSA4KIiCQxIIiISBIDgoiIJDEgiIhIEgOCiIgkMSCIiEgSA4KIiCQxIIiISBIDgoiIJDEgiIhIEgOCiIgkMSCIiEiSrAFhNBoxdOhQ6HQ6rF+/vtp2QRCwePFi6HQ6jBw5EqdOnXK4LxERyUu2gLBYLEhISEBSUhLS09Oxc+dOnD171qqN0WhEXl4evv32WyxatAgLFixwuC8REclLtoAwmUzw9vaGl5cX3NzcEBISgszMTKs2mZmZCA8Ph0KhgL+/P27cuIGrV6861JeIiOSllGvHZrMZarVaXFapVDCZTDW2UavVMJvNDvW1JScn55FrnhnR65H7UuP1OOdUXYrt/YqzS6AGSM7zU7aAEASh2jqFQuFQG0f6SgkMDKxFhUREVBPZAkKtVqOgoEBcNpvN8PT0rLFNQUEBPD09UVlZabcvERHJS7b3IPz8/JCXl4f8/HxUVFQgPT0dWq3Wqo1Wq8W2bdsgCAJOnDiBli1bwtPT06G+REQkL9lGEEqlEvHx8YiOjobFYoFer4ePjw9SU1MBAAaDARqNBllZWdDpdGjWrBmWLFlSY18iIqo/CkFqwp+IiJ54/CY1ERFJYkAQEZEkBgShZ8+eWLp0qbicnJyMVatWObEiepIJggCDwYCsrCxxXUZGBiZPnuzEqp5MDAiCm5sbvv32WxQVFTm7FCIoFAosXLgQS5cuRXl5OcrKyvD+++9j/vz5zi7tiSPbp5jo10OpVCIiIgIbN25EXFyc1bbLly9j7ty5KCoqQtu2bfG3v/0NHTt2dFKl9KTo0aMHXnzxRWzYsAFlZWUICwtDly5dsHXrVnz++eeorKxEQEAA4uPjUVVVhTlz5iA3NxeCIGD8+PF45RV+67wucARBAICJEydix44duHnzptX6RYsWITw8HDt27MDIkSOxePFiJ1VIT5rp06djx44dyM7OxmuvvYbTp09jz549+PLLL7F9+3ZYLBakp6fj1KlTKC4uxo4dO7Bz506Eh4c7u/RGgyMIAgB4eHggLCwMn3zyCdzd3cX1x48fF9+PCAsLw/Lly51VIj1hmjdvjhEjRqB58+Zwc3PDgQMHcPLkSej1egDAnTt3oFarMXjwYJw/fx6LFy+GRqPB4MGDnVx548GAINGf/vQnjBkzBmPGjLHZxpFrYhHVFRcXF7i4/P9Eh16vx4wZM6q1S0tLg9FoxKeffirePoAeH6eYSNS6dWsMGzYMmzdvFtcFBAQgPT0dALBjxw5eEJGcZsCAAdi1a5f4YYri4mJcuXIFRUVFEAQBw4cPR2xsrNWNx+jxcARBViZNmoTPP/9cXH777bcxd+5cJCcni29SEzlDz549MX36dERFRaGqqgpNmjTBggUL4Orqinnz5kEQBCgUCsyaNcvZpTYavNQGERFJ4hQTERFJYkAQEZEkBgQREUliQBARkSQGBBERSeLHXIls2LVrF9atWwdBEFBeXo7nnnsOK1asqJN9r1q1CmVlZXjrrbfqZH9EcmBAEEm4evUqFi5ciK1bt6JDhw4QBAG5ubnOLsuKxWKBq6urs8ugRoxTTEQSrl+/DqVSidatWwO4d4mRZ599FsC9L2z94x//gF6vx0svvYQff/wRK1asQHh4OEJDQ3Hu3DlxP+vXr0doaChCQ0MxZ84c3Lp1q9pz/fLLLxg5ciQOHz4MAMjKysKECRMwZswYRERE4MSJEwCAQ4cOISwsDIsWLcL48eNhNBrl/jHQk04gomosFoswdepUoV+/fkJsbKyQkpIiFBUVCYIgCD169BA+++wzQRAEISMjQ/D39xe+//57QRAEYf369cLMmTMFQRCEffv2CSEhIcLNmzeFqqoqYfbs2cKyZcsEQRCEv//978LSpUuFAwcOCKGhocKZM2cEQRCECxcuCOPHjxdu3rwpCIIgnD59WtBoNIIgCMLBgweFXr16CceOHauvHwM94TjFRCTBxcUFa9aswenTp3HkyBHs3bsXycnJ2LFjBwBg+PDhAIDnnnsOAPD73/8eAODr64s9e/YAAH788UeMGDECHh4eAIDx48djyZIl4nP88MMPyM7ORnJyMlQqFQAgOzsbFy9exMSJE8V2d+/exfXr1wEA3t7eCAgIkPHIif4fA4KoBj169ECPHj0wceJEjBgxQpwGatq0KYB7QeLm5ia2d3Fxwd27dwFAvDaQLV27dsWZM2fw73//WwwIAPjd736HZcuWVWt/7tw5NG/evE6Oi8gRfA+CSILZbMbx48fF5YKCAhQVFaFz584O72PgwIHIyMhAaWkpBEHA5s2bMXDgQHF7p06dkJKSgv/93/9FRkYGAGDQoEHIzs7GmTNnxHYmk6kOjoio9jiCIJJw9+5drFq1CpcvX4a7uzuqqqowY8YM/Pa3v3V4HxqNBr/88gsmTJgA4N7009SpU63aqNVqfPzxx5g8eTJu374NvV6P5cuXY968ebhz5w4qKyvRp08f9O7du06Pj8gRvJorERFJ4hQTERFJYkAQEZEkBgQREUliQBARkSQGBBERSWJAEBGRJAYEERFJ+j/cTV0mxz6RbAAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "from scipy.stats import norm\n",
+ "\n",
+ "# Example: load your dataset\n",
+ "# df = pd.read_csv(\"your_data.csv\")\n",
+ "\n",
+ "# Step 1: aggregate alive/dead counts by smoking\n",
+ "agg = df.groupby('Smoker').agg({\n",
+ " 'alive': 'sum',\n",
+ " 'dead': 'sum'\n",
+ "}).reset_index()\n",
+ "\n",
+ "# Add total and mortality rate\n",
+ "agg['total'] = agg['alive'] + agg['dead']\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# 95% CI for proportion\n",
+ "z = norm.ppf(0.975)\n",
+ "agg['ci_lower'] = agg['mortality_rate'] - z * np.sqrt(\n",
+ " (agg['mortality_rate'] * (1 - agg['mortality_rate'])) / agg['total']\n",
+ ")\n",
+ "agg['ci_upper'] = agg['mortality_rate'] + z * np.sqrt(\n",
+ " (agg['mortality_rate'] * (1 - agg['mortality_rate'])) / agg['total']\n",
+ ")\n",
+ "\n",
+ "print(agg)\n",
+ "\n",
+ "# Plot\n",
+ "sns.barplot(x='Smoker', y='mortality_rate', data=agg, yerr=[\n",
+ " agg['mortality_rate'] - agg['ci_lower'],\n",
+ " agg['ci_upper'] - agg['mortality_rate']\n",
+ "])\n",
+ "plt.ylabel('Mortality Rate')\n",
+ "plt.title('Mortality Rate by Smoking Status')\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "KeyError",
+ "evalue": "'age'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2524\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2525\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2526\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;31mKeyError\u001b[0m: 'age'",
+ "\nDuring handling of the above exception, another exception occurred:\n",
+ "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mbins\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m18\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m34\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m54\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m64\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minf\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mlabels\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'18-34'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'35-54'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'55-64'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'65+'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age_group'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'age'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbins\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mbins\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabels\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlabels\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mright\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;31m# Aggregate\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2137\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_multilevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2138\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2139\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getitem_column\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2140\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2141\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_getitem_column\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m_getitem_column\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 2144\u001b[0m \u001b[0;31m# get column\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2145\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_unique\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2146\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_item_cache\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2147\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2148\u001b[0m \u001b[0;31m# duplicate columns & possible reduce dimensionality\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m_get_item_cache\u001b[0;34m(self, item)\u001b[0m\n\u001b[1;32m 1840\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcache\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1841\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mres\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1842\u001b[0;31m \u001b[0mvalues\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1843\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_box_item_values\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1844\u001b[0m \u001b[0mcache\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, item, fastpath)\u001b[0m\n\u001b[1;32m 3841\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3842\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3843\u001b[0;31m \u001b[0mloc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3844\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3845\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0misna\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36mget_loc\u001b[0;34m(self, key, method, tolerance)\u001b[0m\n\u001b[1;32m 2525\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2526\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2527\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_loc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_maybe_cast_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2528\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2529\u001b[0m \u001b[0mindexer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_indexer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtolerance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtolerance\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;32mpandas/_libs/hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001b[0;34m()\u001b[0m\n",
+ "\u001b[0;31mKeyError\u001b[0m: 'age'"
+ ]
+ }
+ ],
+ "source": [
+ "# Define age groups\n",
+ "bins = [18, 34, 54, 64, np.inf]\n",
+ "labels = ['18-34', '35-54', '55-64', '65+']\n",
+ "df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels, right=True)\n",
+ "\n",
+ "# Aggregate\n",
+ "agg_age = df.groupby(['age_group', 'Smoker']).agg({\n",
+ " 'alive': 'sum',\n",
+ " 'dead': 'sum'\n",
+ "}).reset_index()\n",
+ "\n",
+ "# Add total, mortality, CIs\n",
+ "agg_age['total'] = agg_age['alive'] + agg_age['dead']\n",
+ "agg_age['mortality_rate'] = agg_age['dead'] / agg_age['total']\n",
+ "agg_age['ci_lower'] = agg_age['mortality_rate'] - z * np.sqrt(\n",
+ " (agg_age['mortality_rate'] * (1 - agg_age['mortality_rate'])) / agg_age['total']\n",
+ ")\n",
+ "agg_age['ci_upper'] = agg_age['mortality_rate'] + z * np.sqrt(\n",
+ " (agg_age['mortality_rate'] * (1 - agg_age['mortality_rate'])) / agg_age['total']\n",
+ ")\n",
+ "\n",
+ "print(agg_age)\n",
+ "\n",
+ "# Plot\n",
+ "sns.barplot(x='age_group', y='mortality_rate', hue='Smoker', data=agg_age)\n",
+ "plt.ylabel('Mortality Rate')\n",
+ "plt.title('Mortality Rate by Smoking Status and Age Group')\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Index(['Smoker', 'Status', 'Age', 'Death', 'AgeGroup', 'alive', 'dead'], dtype='object')"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.columns\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "aggregate() missing 1 required positional argument: 'arg'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 6\u001b[0m agg = df.groupby('AgeGroup').agg(\n\u001b[1;32m 7\u001b[0m \u001b[0malive\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'alive'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mdead\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'dead'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m ).reset_index()\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mTypeError\u001b[0m: aggregate() missing 1 required positional argument: 'arg'"
+ ]
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "\n",
+ "# Step 2: Aggregate by AgeGroup\n",
+ "agg = df.groupby('AgeGroup').agg(\n",
+ " alive=('alive', 'sum'),\n",
+ " dead=('dead', 'sum')\n",
+ ").reset_index()\n",
+ "\n",
+ "# Total in each group\n",
+ "agg['total'] = agg['alive'] + agg['dead']\n",
+ "\n",
+ "# Mortality rate\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# Wilson confidence intervals\n",
+ "cis_age = agg.apply(\n",
+ " lambda row: proportion_confint(\n",
+ " count=int(row['dead']),\n",
+ " nobs=int(row['total']),\n",
+ " alpha=0.05,\n",
+ " method='wilson'\n",
+ " ),\n",
+ " axis=1\n",
+ ")\n",
+ "\n",
+ "agg['ci_lower'] = [c[0] for c in cis_age]\n",
+ "agg['ci_upper'] = [c[1] for c in cis_age]\n",
+ "\n",
+ "agg\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "aggregate() missing 1 required positional argument: 'arg'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 10\u001b[0m agg = df.groupby('AgeGroup').agg(\n\u001b[1;32m 11\u001b[0m \u001b[0malive\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'alive'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mdead\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'dead'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'sum'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m ).reset_index()\n\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mTypeError\u001b[0m: aggregate() missing 1 required positional argument: 'arg'"
+ ]
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "\n",
+ "# Step 1: Create alive/dead indicator columns\n",
+ "df['alive'] = (df['Status'] == 'Alive').astype(int)\n",
+ "df['dead'] = (df['Status'] == 'Dead').astype(int)\n",
+ "\n",
+ "# Step 2: Aggregate by AgeGroup\n",
+ "agg = df.groupby('AgeGroup').agg(\n",
+ " alive=('alive', 'sum'),\n",
+ " dead=('dead', 'sum')\n",
+ ").reset_index()\n",
+ "\n",
+ "# Total in each group\n",
+ "agg['total'] = agg['alive'] + agg['dead']\n",
+ "\n",
+ "# Mortality rate\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# Wilson confidence intervals\n",
+ "cis_age = agg.apply(\n",
+ " lambda row: proportion_confint(\n",
+ " count=int(row['dead']),\n",
+ " nobs=int(row['total']),\n",
+ " alpha=0.05,\n",
+ " method='wilson'\n",
+ " ),\n",
+ " axis=1\n",
+ ")\n",
+ "\n",
+ "agg['ci_lower'] = [c[0] for c in cis_age]\n",
+ "agg['ci_upper'] = [c[1] for c in cis_age]\n",
+ "\n",
+ "agg\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " AgeGroup | \n",
+ " alive | \n",
+ " dead | \n",
+ " total | \n",
+ " mortality_rate | \n",
+ " ci_lower | \n",
+ " ci_upper | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 18-34 | \n",
+ " 389 | \n",
+ " 11 | \n",
+ " 400 | \n",
+ " 0.027500 | \n",
+ " 0.015424 | \n",
+ " 0.048565 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 34-54 | \n",
+ " 376 | \n",
+ " 60 | \n",
+ " 436 | \n",
+ " 0.137615 | \n",
+ " 0.108430 | \n",
+ " 0.173129 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 55-64 | \n",
+ " 145 | \n",
+ " 91 | \n",
+ " 236 | \n",
+ " 0.385593 | \n",
+ " 0.325799 | \n",
+ " 0.449053 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 65+ | \n",
+ " 35 | \n",
+ " 207 | \n",
+ " 242 | \n",
+ " 0.855372 | \n",
+ " 0.805503 | \n",
+ " 0.894135 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " AgeGroup alive dead total mortality_rate ci_lower ci_upper\n",
+ "0 18-34 389 11 400 0.027500 0.015424 0.048565\n",
+ "1 34-54 376 60 436 0.137615 0.108430 0.173129\n",
+ "2 55-64 145 91 236 0.385593 0.325799 0.449053\n",
+ "3 65+ 35 207 242 0.855372 0.805503 0.894135"
+ ]
+ },
+ "execution_count": 28,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Step 1: Create alive/dead columns\n",
+ "df['alive'] = (df['Status'] == 'Alive').astype(int)\n",
+ "df['dead'] = (df['Status'] == 'Dead').astype(int)\n",
+ "\n",
+ "# Step 2: Aggregate using old syntax\n",
+ "agg = df.groupby('AgeGroup').agg({\n",
+ " 'alive': 'sum',\n",
+ " 'dead': 'sum'\n",
+ "}).reset_index()\n",
+ "\n",
+ "# Total in each group\n",
+ "agg['total'] = agg['alive'] + agg['dead']\n",
+ "\n",
+ "# Mortality rate\n",
+ "agg['mortality_rate'] = agg['dead'] / agg['total']\n",
+ "\n",
+ "# Confidence intervals\n",
+ "from statsmodels.stats.proportion import proportion_confint\n",
+ "ci_bounds = [proportion_confint(row['dead'], row['total'], alpha=0.05, method='wilson')\n",
+ " for _, row in agg.iterrows()]\n",
+ "agg['ci_lower'] = [c[0] for c in ci_bounds]\n",
+ "agg['ci_upper'] = [c[1] for c in ci_bounds]\n",
+ "\n",
+ "agg\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " AgeGroup | \n",
+ " Smoker | \n",
+ " alive | \n",
+ " dead | \n",
+ " total | \n",
+ " mortality_rate | \n",
+ " ci_lower | \n",
+ " ci_upper | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 18-34 | \n",
+ " No | \n",
+ " 213 | \n",
+ " 6 | \n",
+ " 219 | \n",
+ " 0.027397 | \n",
+ " 0.012616 | \n",
+ " 0.058473 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 18-34 | \n",
+ " Yes | \n",
+ " 176 | \n",
+ " 5 | \n",
+ " 181 | \n",
+ " 0.027624 | \n",
+ " 0.011856 | \n",
+ " 0.063027 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 34-54 | \n",
+ " No | \n",
+ " 180 | \n",
+ " 19 | \n",
+ " 199 | \n",
+ " 0.095477 | \n",
+ " 0.061977 | \n",
+ " 0.144299 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 34-54 | \n",
+ " Yes | \n",
+ " 196 | \n",
+ " 41 | \n",
+ " 237 | \n",
+ " 0.172996 | \n",
+ " 0.130158 | \n",
+ " 0.226265 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 55-64 | \n",
+ " No | \n",
+ " 81 | \n",
+ " 40 | \n",
+ " 121 | \n",
+ " 0.330579 | \n",
+ " 0.253108 | \n",
+ " 0.418476 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " 55-64 | \n",
+ " Yes | \n",
+ " 64 | \n",
+ " 51 | \n",
+ " 115 | \n",
+ " 0.443478 | \n",
+ " 0.355968 | \n",
+ " 0.534642 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " 65+ | \n",
+ " No | \n",
+ " 28 | \n",
+ " 165 | \n",
+ " 193 | \n",
+ " 0.854922 | \n",
+ " 0.798312 | \n",
+ " 0.897680 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " 65+ | \n",
+ " Yes | \n",
+ " 7 | \n",
+ " 42 | \n",
+ " 49 | \n",
+ " 0.857143 | \n",
+ " 0.733323 | \n",
+ " 0.929036 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " AgeGroup Smoker alive dead total mortality_rate ci_lower ci_upper\n",
+ "0 18-34 No 213 6 219 0.027397 0.012616 0.058473\n",
+ "1 18-34 Yes 176 5 181 0.027624 0.011856 0.063027\n",
+ "2 34-54 No 180 19 199 0.095477 0.061977 0.144299\n",
+ "3 34-54 Yes 196 41 237 0.172996 0.130158 0.226265\n",
+ "4 55-64 No 81 40 121 0.330579 0.253108 0.418476\n",
+ "5 55-64 Yes 64 51 115 0.443478 0.355968 0.534642\n",
+ "6 65+ No 28 165 193 0.854922 0.798312 0.897680\n",
+ "7 65+ Yes 7 42 49 0.857143 0.733323 0.929036"
+ ]
+ },
+ "execution_count": 29,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Group by AgeGroup & Smoker\n",
+ "agg2 = df.groupby(['AgeGroup', 'Smoker']).agg({\n",
+ " 'alive': 'sum',\n",
+ " 'dead': 'sum'\n",
+ "}).reset_index()\n",
+ "\n",
+ "# Totals and mortality rates\n",
+ "agg2['total'] = agg2['alive'] + agg2['dead']\n",
+ "agg2['mortality_rate'] = agg2['dead'] / agg2['total']\n",
+ "\n",
+ "# Confidence intervals\n",
+ "ci_bounds2 = [proportion_confint(row['dead'], row['total'], alpha=0.05, method='wilson')\n",
+ " for _, row in agg2.iterrows()]\n",
+ "agg2['ci_lower'] = [c[0] for c in ci_bounds2]\n",
+ "agg2['ci_upper'] = [c[1] for c in ci_bounds2]\n",
+ "\n",
+ "agg2\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Optimization terminated successfully.\n",
+ " Current function value: 0.412727\n",
+ " Iterations 7\n",
+ "Optimization terminated successfully.\n",
+ " Current function value: 0.354560\n",
+ " Iterations 7\n"
+ ]
+ },
+ {
+ "ename": "AttributeError",
+ "evalue": "'LogitResults' object has no attribute 'get_prediction'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mage_range\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlinspace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Age\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Age\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0mpred_smokers\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel_smokers\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_prediction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"Age\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mage_range\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 18\u001b[0m \u001b[0mpred_nonsmokers\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel_nonsmokers\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_prediction\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDataFrame\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"Age\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mage_range\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/opt/conda/lib/python3.6/site-packages/statsmodels/base/wrapper.py\u001b[0m in \u001b[0;36m__getattribute__\u001b[0;34m(self, attr)\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 35\u001b[0;31m \u001b[0mobj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresults\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 36\u001b[0m \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresults\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 37\u001b[0m \u001b[0mhow\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_wrap_attrs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mAttributeError\u001b[0m: 'LogitResults' object has no attribute 'get_prediction'"
+ ]
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "import statsmodels.api as sm\n",
+ "import statsmodels.formula.api as smf\n",
+ "\n",
+ "# Logistic regression for smokers\n",
+ "model_smokers = smf.logit(\"Death ~ Age\", data=df[df[\"Smoker\"] == \"Yes\"]).fit()\n",
+ "\n",
+ "# Logistic regression for non-smokers\n",
+ "model_nonsmokers = smf.logit(\"Death ~ Age\", data=df[df[\"Smoker\"] == \"No\"]).fit()\n",
+ "\n",
+ "# Create a dataframe for predictions\n",
+ "age_range = np.linspace(df[\"Age\"].min(), df[\"Age\"].max(), 100)\n",
+ "\n",
+ "pred_smokers = model_smokers.get_prediction(pd.DataFrame({\"Age\": age_range}))\n",
+ "pred_nonsmokers = model_nonsmokers.get_prediction(pd.DataFrame({\"Age\": age_range}))\n",
+ "\n",
+ "# Put into DataFrames\n",
+ "smokers_df = pd.DataFrame({\n",
+ " \"Age\": age_range,\n",
+ " \"Predicted\": pred_smokers.predicted_mean,\n",
+ " \"Lower\": pred_smokers.conf_int()[:,0],\n",
+ " \"Upper\": pred_smokers.conf_int()[:,1],\n",
+ " \"Smoker\": \"Yes\"\n",
+ "})\n",
+ "\n",
+ "nonsmokers_df = pd.DataFrame({\n",
+ " \"Age\": age_range,\n",
+ " \"Predicted\": pred_nonsmokers.predicted_mean,\n",
+ " \"Lower\": pred_nonsmokers.conf_int()[:,0],\n",
+ " \"Upper\": pred_nonsmokers.conf_int()[:,1],\n",
+ " \"Smoker\": \"No\"\n",
+ "})\n",
+ "\n",
+ "plot_df = pd.concat([smokers_df, nonsmokers_df])\n",
+ "\n",
+ "# Plot\n",
+ "plt.figure(figsize=(8,6))\n",
+ "sns.lineplot(data=plot_df, x=\"Age\", y=\"Predicted\", hue=\"Smoker\")\n",
+ "plt.fill_between(smokers_df[\"Age\"], smokers_df[\"Lower\"], smokers_df[\"Upper\"], color=\"red\", alpha=0.2)\n",
+ "plt.fill_between(nonsmokers_df[\"Age\"], nonsmokers_df[\"Lower\"], nonsmokers_df[\"Upper\"], color=\"blue\", alpha=0.2)\n",
+ "plt.ylabel(\"Probability of Death\")\n",
+ "plt.title(\"Logistic Regression: Death Probability vs Age\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Optimization terminated successfully.\n",
+ " Current function value: 0.412727\n",
+ " Iterations 7\n",
+ "Optimization terminated successfully.\n",
+ " Current function value: 0.354560\n",
+ " Iterations 7\n"
+ ]
+ },
+ {
+ "ename": "AttributeError",
+ "evalue": "module 'seaborn' has no attribute 'lineplot'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 40\u001b[0m \u001b[0;31m# Plot\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m8\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 42\u001b[0;31m \u001b[0msns\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlineplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mplot_df\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Age\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Predicted\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhue\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Smoker\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 43\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0msmoker_val\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Yes\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"No\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m\"red\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"blue\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[0msubset\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplot_df\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mplot_df\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"Smoker\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0msmoker_val\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mAttributeError\u001b[0m: module 'seaborn' has no attribute 'lineplot'"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import matplotlib.pyplot as plt\n",
+ "import seaborn as sns\n",
+ "import statsmodels.api as sm\n",
+ "import statsmodels.formula.api as smf\n",
+ "\n",
+ "# Fit models separately\n",
+ "model_smokers = smf.logit(\"Death ~ Age\", data=df[df[\"Smoker\"] == \"Yes\"]).fit()\n",
+ "model_nonsmokers = smf.logit(\"Death ~ Age\", data=df[df[\"Smoker\"] == \"No\"]).fit()\n",
+ "\n",
+ "# Prediction age range\n",
+ "age_range = np.linspace(df[\"Age\"].min(), df[\"Age\"].max(), 100)\n",
+ "\n",
+ "def pred_ci(model, age_vals):\n",
+ " X = sm.add_constant(pd.DataFrame({\"Age\": age_vals}))\n",
+ " pred_probs = model.predict(X)\n",
+ " # standard errors for log-odds\n",
+ " se = np.sqrt(np.diag(np.dot(np.dot(X, model.cov_params()), X.T)))\n",
+ " # 95% CI in log-odds, then convert to probability\n",
+ " logit = np.log(pred_probs / (1 - pred_probs))\n",
+ " ci_lower = 1 / (1 + np.exp(-(logit - 1.96 * se)))\n",
+ " ci_upper = 1 / (1 + np.exp(-(logit + 1.96 * se)))\n",
+ " return pred_probs, ci_lower, ci_upper\n",
+ "\n",
+ "# Predictions for smokers\n",
+ "pred_s, lower_s, upper_s = pred_ci(model_smokers, age_range)\n",
+ "# Predictions for non-smokers\n",
+ "pred_n, lower_n, upper_n = pred_ci(model_nonsmokers, age_range)\n",
+ "\n",
+ "# Create plot DataFrame\n",
+ "plot_df = pd.DataFrame({\n",
+ " \"Age\": np.concatenate([age_range, age_range]),\n",
+ " \"Predicted\": np.concatenate([pred_s, pred_n]),\n",
+ " \"Lower\": np.concatenate([lower_s, lower_n]),\n",
+ " \"Upper\": np.concatenate([upper_s, upper_n]),\n",
+ " \"Smoker\": [\"Yes\"]*len(age_range) + [\"No\"]*len(age_range)\n",
+ "})\n",
+ "\n",
+ "# Plot\n",
+ "plt.figure(figsize=(8,6))\n",
+ "sns.lineplot(data=plot_df, x=\"Age\", y=\"Predicted\", hue=\"Smoker\")\n",
+ "for smoker_val, color in zip([\"Yes\", \"No\"], [\"red\", \"blue\"]):\n",
+ " subset = plot_df[plot_df[\"Smoker\"] == smoker_val]\n",
+ " plt.fill_between(subset[\"Age\"], subset[\"Lower\"], subset[\"Upper\"], color=color, alpha=0.2)\n",
+ "\n",
+ "plt.ylabel(\"Probability of Death\")\n",
+ "plt.title(\"Logistic Regression: Death Probability vs Age\")\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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NNX7G1yv13P27Fkef/xxGjRowNixYwF44IEH2LJlCxcvXgQgPz+fgwcPAuaAr1ar8fT0xGg0snHjRkuzMJg/08TEREwmU7XmtTxDhgzh2LFj/PzzzxgMBrZv345Wq6VTp06WYz7++GNSUlLIyclh8+bNDB061FIWBwcHGjRoQE5ODhs3brwh/S+//JKoqCiKi4tZv349gwYNKvMzq0ijRo2Ij48v9dyAAQP466+/+OCDD0o1XZdl6NCh/Pjjj+zYscPSlA5YfT8dPnwYtVrN/v372bt3L3v37uXAgQN07dqVvXv3olarGThwIBs3bqS4uJhLly7xxRdfWM6/7777iI2NZe/evRgMBgwGAxERETcMIJRqhwzi0g1mzJhB+/btLX8bNmygZ8+ezJs3j7lz59K7d2/i4+Mtc7o9PT1Zv349q1evpnv37kRFRXHXXXeV2YxXWFjIc889R7du3ejbty8eHh6WhTDGjx9PVFQUXbt25bHHHrvh3EceeYQhQ4Ywbdo0OnfuzLPPPmsZWVyZ++67D3d3dz777DPUajVvv/02586do3///vTo0YPnnnvOEnwef/xx/Pz86N+/P1OnTmXQoEFotdpy064sve+//55hw4bRqVMnXn75ZdatW4eDgwMZGRk88cQTdOnShaFDh9KtW7cya7vjxo1j5MiRTJkyhf79+6PVann++eetKvfJkydLBbCyXJ0R0K1bN5YsWULbtm355JNPcHZ2BmDgwIFMnz6dBQsW0LlzZ4YPH25p3u7duzf33nsvgwYNol+/fjg4OJRqeh08eDAA3bt3r5V5782aNWP16tWsWLGCHj168O2337Jp06ZSn9/w4cOZNm0aAwYMICgoiNmzZwPw8MMPU1JSQo8ePZgwYQL33HPPDemPGjWKpUuX0qtXL/R6fbnN3hWZM2cOS5cupWvXrpZxE46OjvzjH/8gISGBgQMHVni+j48PHTt25PTp05YfIIDV99OePXsYO3YsAQEBeHt7W/4mT57MV199hdFoZNmyZeTn59OrVy8WL17MsGHDLO+hq6sr27Zt48CBA9xzzz307t2bNWvWyLnmdUQlrm0rkqRqYDKZuPfee1mzZg09evSo6+zctI8//pgDBw5UWiOXpJuxceNGYmNjWbNmTV1n5QarV68mIyOj1LgI6dYga+JStfj+++/Jy8tDr9ezadMmAMso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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plt.figure(figsize=(8,6))\n",
+ "\n",
+ "# Smokers\n",
+ "plt.plot(age_range, pred_s, color=\"red\", label=\"Smokers\")\n",
+ "plt.fill_between(age_range, lower_s, upper_s, color=\"red\", alpha=0.2)\n",
+ "\n",
+ "# Non-smokers\n",
+ "plt.plot(age_range, pred_n, color=\"blue\", label=\"Non-smokers\")\n",
+ "plt.fill_between(age_range, lower_n, upper_n, color=\"blue\", alpha=0.2)\n",
+ "\n",
+ "plt.xlabel(\"Age\")\n",
+ "plt.ylabel(\"Probability of Death\")\n",
+ "plt.title(\"Logistic Regression: Death Probability vs Age\")\n",
+ "plt.legend()\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
@@ -16,10 +1912,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.3"
+ "version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
-