From 0c957990b0887923223be993697ce09402d79e46 Mon Sep 17 00:00:00 2001 From: DBras Date: Tue, 19 May 2026 14:56:10 +0200 Subject: [PATCH] 2x2-tabel --- 2x2-tabel.ipynb | 262 ++++++++++++++++++++++++++++++++++++++++++++ Formelsamling.ipynb | 34 +++--- 2 files changed, 276 insertions(+), 20 deletions(-) create mode 100644 2x2-tabel.ipynb diff --git a/2x2-tabel.ipynb b/2x2-tabel.ipynb new file mode 100644 index 0000000..a59b058 --- /dev/null +++ b/2x2-tabel.ipynb @@ -0,0 +1,262 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "bac57c6e-48a0-4414-bf65-ed4ff751aa87", + "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": "1616dacd-4132-46dd-a1a0-df813b634b12", + "metadata": {}, + "source": [ + "# Sensitivitet, specificitet og positiv/negativ prædiktiv værdi" + ] + }, + { + "cell_type": "markdown", + "id": "ad5c44e5-dc99-4665-a1c2-1b9b1586a175", + "metadata": {}, + "source": [ + "$$\n", + "Sensitivitet = P(Positiv\\ test | syg) = \\frac{antal\\ sandt\\ positive}{antal\\ sandt\\ positive + antal\\ falsk\\ negative}\n", + "$$\n", + "\n", + "$$\n", + "Specificitet = P(Negativ\\ test|rask) = \\frac{antal\\ sandt\\ negative}{antal\\ sandt\\ negative + antal\\ falsk\\ positive}\n", + "$$\n", + "\n", + "$$\n", + "PPV = P(Syg|positiv\\ test) = \\frac{antal\\ sande\\ positive}{antal\\ sande\\ positive + antal\\ falske\\ positive}\n", + "$$\n", + "\n", + "$$\n", + "NPV = P(Rask|negativ\\ test) = \\frac{antal\\ sande\\ negative}{antal\\ sande\\ negative + antal\\ falske\\ negative}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "c220e249-002a-4536-8e87-424acb2e8190", + "metadata": {}, + "source": [ + "## Tabel ud fra positive og negative\n", + "\n", + "| | Syg | Ikke syg | I alt |\n", + "| :----------- | :--------------: | :--------------: | --------------------------------: |\n", + "| Test positiv | _sandt positive_ | _falsk positive_ | Total positive |\n", + "| Test negativ | _falsk negative_ | _sandt negative_ | Total negative |\n", + "| I alt | Total syge | Total raske | **n** |" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "af36924c-e2e7-46cf-9bde-5a94b9d427e3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "\n", + "### 2x2-tabel\n", + "\n", + "| | Syg | Ikke syg | I alt |\n", + "| :----------- | :--------------: | :--------------: | --------------------------------: |\n", + "| Test positiv | 117 | 796 | 913 |\n", + "| Test negativ | 20 | 3142 | 3162 |\n", + "| I alt | 137 | 3938 | **4075** |\n", + "\n", + "Sensitivitet $= 85.40%$\\%\n", + "\n", + "Specificitet $= 79.79%$\\%\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sandt_positive = 117\n", + "sandt_negative = 3142\n", + "\n", + "falsk_positive = 796\n", + "falsk_negative = 20\n", + "\n", + "\n", + "############################################\n", + "sensitivitet = sandt_positive / (sandt_positive + falsk_negative)\n", + "specificitet = sandt_negative / (sandt_negative + falsk_positive)\n", + "ppv = sandt_positive / (sandt_positive + falsk_positive)\n", + "npv = sandt_negative / (sandt_negative + falsk_negative)\n", + "\n", + "sum_syge = sandt_positive + falsk_negative\n", + "sum_ikke_syge = falsk_positive + sandt_negative\n", + "sum_positive = sandt_positive + falsk_positive\n", + "sum_negative = sandt_negative + falsk_negative\n", + "\n", + "display(Markdown(\n", + " rf\"\"\"\n", + "### 2x2-tabel\n", + " \n", + "| | Syg | Ikke syg | I alt |\n", + "| :----------- | :--------------: | :--------------: | --------------------------------: |\n", + "| Test positiv | {sandt_positive} | {falsk_positive} | {sum_positive} |\n", + "| Test negativ | {falsk_negative} | {sandt_negative} | {sum_negative} |\n", + "| I alt | {sum_syge} | {sum_ikke_syge} | **{sum_positive + sum_negative}** |\n", + "\n", + "Sensitivitet $= {sensitivitet:.2%}$\\%\n", + "\n", + "Specificitet $= {specificitet:.2%}$\\%\n", + "\n", + "\n", + "\"\"\"\n", + "))" + ] + }, + { + "cell_type": "markdown", + "id": "d72087c9-96b0-4584-bae2-854068fb9de5", + "metadata": {}, + "source": [ + "## Værdier ud fra sensitivitet, specificitet og prævalens" + ] + }, + { + "cell_type": "markdown", + "id": "833a7a8d-f012-4a0f-b39d-fc1ae3d8a1b1", + "metadata": {}, + "source": [ + "$$\n", + "PPV = \\frac{sensitivitet \\cdot prævalens}{sensitivitet \\cdot prævalens + (1-specificitet) \\cdot (1-prævalens)}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0b81b6b9-268a-4338-bff9-d5a7c1636a67", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "\n", + "$$\n", + "PPV = \\frac{sensitivitet \\cdot prævalens}{sensitivitet \\cdot prævalens + (1-specificitet) \\cdot (1-prævalens)}\n", + "$$\n", + "$$\n", + "= \\frac{0.854 \\cdot 0.05}{0.854 \\cdot 0.05 + (1-0.798) \\cdot (1-0.05)}\n", + "$$\n", + "$$\n", + "= 18.20%\n", + "\\%\n", + "$$\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sensitivitet = 0.854\n", + "specificitet = 0.798\n", + "prævalens = 0.05\n", + "\n", + "ppv = sensitivitet * prævalens / (sensitivitet * prævalens + (1-specificitet) * (1-prævalens))\n", + "\n", + "display(Markdown(\n", + " rf\"\"\"\n", + "$$\n", + "PPV = \\frac{{sensitivitet \\cdot prævalens}}{{sensitivitet \\cdot prævalens + (1-specificitet) \\cdot (1-prævalens)}}\n", + "$$\n", + "$$\n", + "= \\frac{{{sensitivitet} \\cdot {prævalens}}}{{{sensitivitet} \\cdot {prævalens} + (1-{specificitet}) \\cdot (1-{prævalens})}}\n", + "$$\n", + "$$\n", + "= {ppv:.2%}\n", + "\\%\n", + "$$\n", + "\"\"\"\n", + "))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6fab8ba-02cc-478d-b3f0-32d55c6400c8", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.14.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Formelsamling.ipynb b/Formelsamling.ipynb index f559d79..531f39c 100644 --- a/Formelsamling.ipynb +++ b/Formelsamling.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "id": "b9802fc2", "metadata": {}, "outputs": [], @@ -143,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 6, "id": "1774cb7c", "metadata": {}, "outputs": [ @@ -151,7 +151,7 @@ "data": { "text/markdown": [ "\n", - "### Data\n", + "### 2x2-tabel\n", "\n", "| | Syg | Ikke syg | I alt |\n", "| :----------- | :--------------: | :--------------: | --------------------------------: |\n", @@ -159,15 +159,11 @@ "| Test negativ | 20 | 3142 | 3162 |\n", "| I alt | 137 | 3938 | **4075** |\n", "\n", + "Sensitivitet $= 85.40%$\\%\n", "\n", - "### Nøgleværdier\n", + "Specificitet $= 79.79%$\\%\n", "\n", - "| | |\n", - "| ---------------- | ------------------ |\n", - "| **Sensitivitet** | 85.4% |\n", - "| **Specificitet** | 79.8% |\n", - "| **PPV** | 12.8% |\n", - "| **NPV** | 99.4% |\n" + "\n" ], "text/plain": [ "" @@ -184,6 +180,8 @@ "falsk_positive = 796\n", "falsk_negative = 20\n", "\n", + "\n", + "############################################\n", "sensitivitet = sandt_positive / (sandt_positive + falsk_negative)\n", "specificitet = sandt_negative / (sandt_negative + falsk_positive)\n", "ppv = sandt_positive / (sandt_positive + falsk_positive)\n", @@ -196,7 +194,7 @@ "\n", "display(Markdown(\n", " rf\"\"\"\n", - "### Data\n", + "### 2x2-tabel\n", " \n", "| | Syg | Ikke syg | I alt |\n", "| :----------- | :--------------: | :--------------: | --------------------------------: |\n", @@ -204,15 +202,11 @@ "| Test negativ | {falsk_negative} | {sandt_negative} | {sum_negative} |\n", "| I alt | {sum_syge} | {sum_ikke_syge} | **{sum_positive + sum_negative}** |\n", "\n", + "Sensitivitet $= {sensitivitet:.2%}$\\%\n", + "\n", + "Specificitet $= {specificitet:.2%}$\\%\n", "\n", - "### Nøgleværdier\n", "\n", - "| | |\n", - "| ---------------- | ------------------ |\n", - "| **Sensitivitet** | {sensitivitet:.1%} |\n", - "| **Specificitet** | {specificitet:.1%} |\n", - "| **PPV** | {ppv:.1%} |\n", - "| **NPV** | {npv:.1%} |\n", "\"\"\"\n", "))" ] @@ -727,7 +721,7 @@ ], "metadata": { "kernelspec": { - "display_name": "base", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -741,7 +735,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.9" + "version": "3.14.5" } }, "nbformat": 4,