{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "42259d82",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Imports\n",
    "\n",
    "from IPython.display import display, Markdown\n",
    "from scipy.stats import chi2_contingency\n",
    "from scipy.stats import t as t_test\n",
    "import numpy as np\n",
    "t_value = t_test.isf\n",
    "\n",
    "def _display_table(data_array, row_names=None, col_names=None):\n",
    "    _row_num = len(data_array)\n",
    "    _col_num = len(data_array[0])\n",
    "    _rows = []\n",
    "    for i in range(_row_num):\n",
    "        row = f'| {row_names[i]} |'\n",
    "        for j in range(_col_num):\n",
    "            row += f' {data_array[i][j]:.1f} |'\n",
    "        row += f' {sum(data_array[i]):.0f} |'\n",
    "        _rows.append(row)\n",
    "    _total_row = '| **Total** |'\n",
    "    _col_tots = 0\n",
    "    for i in range(_col_num):\n",
    "        col_tot = 0\n",
    "        for j in range(_row_num):\n",
    "            col_tot += data_array[j][i]\n",
    "        _col_tots += col_tot\n",
    "        _total_row += f' **{col_tot:.0f}** |'\n",
    "    _total_row += f' **{_col_tots:.0f}** |'\n",
    "    display(Markdown(\n",
    "    rf\"\"\"\n",
    "| | {' | '.join(col_names + ['Total'])} |\n",
    "{'|-'*(len(row_names) + 2)} |\n",
    "{'\\n'.join(_rows)}\n",
    "{_total_row}\n",
    "\"\"\"\n",
    "))\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ef266dc",
   "metadata": {},
   "source": [
    "# $\\Chi^2$-test\n",
    "\n",
    "| | Kolonne 1| Kolonne 2 |\n",
    "|-|---------|---------|\n",
    "|Række 1| R1 K1| R1 K2|\n",
    "|Række 2| R2 K1| R2 K2|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7c426592",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "$H_0$: $\\pi_1 = \\pi_0$, altså ingen sammenhæng mellem rækker og søjler, hvilket vil sige ingen sammenhæng mellem eksponering og udfald."
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Observeret:"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n",
       "| | Hovedpine | Ingen hovedpine | Total |\n",
       "|-|-|-|- |\n",
       "| Høj skærmtid | 210.0 | 250.0 | 460 |\n",
       "| Lav skærmtid | 90.0 | 270.0 | 360 |\n",
       "| **Total** | **300** | **520** | **820** |\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "### Forventet:"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n",
       "| | Hovedpine | Ingen hovedpine | Total |\n",
       "|-|-|-|- |\n",
       "| Høj skærmtid | 168.3 | 291.7 | 460 |\n",
       "| Lav skærmtid | 131.7 | 228.3 | 360 |\n",
       "| **Total** | **300** | **520** | **820** |\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n",
       "Frihedsgrader: 1\n",
       "\n",
       "Udregnet ved brug af Python-biblioteket `scipy.stats.chi2_contingency`:\n",
       "\n",
       "$\\Chi^2$-værdi/teststørrelse: 36.24\n",
       "\n",
       "$p$-værdi: 1.7e-09 $\\ll 0.05$\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n",
       "Da $p$ $\\ll 0.05$, kan nulhypotesen $\\pi_1 = \\pi_0$ forkastes. Der er altså signifikant sammenhæng mellem udfald og eksponering.\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "kolonner = ['Hovedpine', 'Ingen hovedpine']\n",
    "rækker = ['Høj skærmtid',\n",
    "          'Lav skærmtid']\n",
    "data = [[210, 250],         # R1 K1  ,  R1 K2\n",
    "        [90, 270]]          # R2 K1  ,  R2 K2\n",
    "\n",
    "\n",
    "\n",
    "############################################\n",
    "stat, p, dof, expected = chi2_contingency(data)\n",
    "p_threshold = 0.05\n",
    "match p:\n",
    "    case p if p >= p_threshold:\n",
    "        p_text = f'$\\ge {p_threshold}$'\n",
    "    case p if p < p_threshold/100:\n",
    "        p_text = f'$\\ll {p_threshold}$'\n",
    "    case _:\n",
    "        p_text = f'$\\lt {p_threshold}$'\n",
    "\n",
    "display(Markdown(rf\"$H_0$: $\\pi_1 = \\pi_0$, altså ingen sammenhæng mellem rækker og søjler, hvilket vil sige ingen sammenhæng mellem eksponering og udfald.\"))\n",
    "display(Markdown('### Observeret:'))\n",
    "_display_table(data, rækker, kolonner)\n",
    "display(Markdown('### Forventet:'))\n",
    "_display_table(expected, rækker, kolonner)\n",
    "\n",
    "display(Markdown(\n",
    "    rf\"\"\"\n",
    "Frihedsgrader: {dof}\n",
    "\n",
    "Udregnet ved brug af Python-biblioteket `scipy.stats.chi2_contingency`:\n",
    "\n",
    "$\\Chi^2$-værdi (teststørrelse): {stat:.2f}\n",
    "\n",
    "$p$-værdi: {p:.2} {p_text}\n",
    "\"\"\"\n",
    "))\n",
    "\n",
    "if p < p_threshold:\n",
    "    display(Markdown(\n",
    "        rf\"\"\"\n",
    "Da $p$ {p_text}, kan nulhypotesen $\\pi_1 = \\pi_0$ forkastes. Der er altså signifikant sammenhæng mellem udfald og eksponering.\n",
    "\"\"\"\n",
    "    ))\n",
    "\n",
    "else:\n",
    "    display(Markdown(\n",
    "        rf\"\"\"\n",
    "Da $p$ {p_text}, kan nulhypotesen $\\pi_1 = \\pi_0$ ikke forkastes. Altså kan uafhængighed mellem udfald og eksponering ikke afvises.\n",
    "\"\"\"\n",
    "    ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "896b2de0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
