master b639b397df19
49 files
5.1 MB
1.3M tokens
Showing preview only (5,332K chars total). The displayed content is truncated. Use the JSON API for full output.
Repository: pzivich/Python-for-Epidemiologists
Branch: master
Commit: b639b397df19
Files: 49
Total size: 5.1 MB

Directory structure:
gitextract_95lr8jsa/

├── .gitignore
├── 1_Python-Basics/
│   └── intro_to_python.ipynb
├── 2_Data-Basics/
│   ├── 1_data_management.ipynb
│   ├── 2_intro_to_plots.ipynb
│   ├── 3_simulating_data.ipynb
│   ├── sample_csv.csv
│   └── sample_sas.sas7bdat
├── 3_Epidemiology_Analysis/
│   ├── a_basics/
│   │   ├── 1_basic_measures.ipynb
│   │   └── 2_functional_forms.ipynb
│   ├── b_missing_data/
│   │   ├── 1_IPMW_one_variable.ipynb
│   │   └── 4_IPCW.ipynb
│   ├── c_causal_inference/
│   │   ├── 1_time-fixed-treatments/
│   │   │   ├── 01_g-formula.ipynb
│   │   │   ├── 02_gformula_stochastic.ipynb
│   │   │   ├── 03_IPTW_intro.ipynb
│   │   │   ├── 04_IPTW_SMR.ipynb
│   │   │   ├── 05_AIPTW_intro.ipynb
│   │   │   ├── 06_AIPTW_continuous.ipynb
│   │   │   ├── 07_TMLE_intro.ipynb
│   │   │   ├── 08_TMLE_continuous.ipynb
│   │   │   ├── 09_TMLE_missing_data.ipynb
│   │   │   └── 10_TMLE_stochastic.ipynb
│   │   ├── 2-time-varying-treatments/
│   │   │   ├── 1_MonteCarlo_G-formula.ipynb
│   │   │   ├── 2_MonteCarlo_G-formula_keil2014.ipynb
│   │   │   └── 4_IterativeConditional_GFormula.ipynb
│   │   ├── 3-generalizability-transportability/
│   │   │   ├── 1-generalizability.ipynb
│   │   │   └── README.md
│   │   └── README.md
│   └── d_sensitivity_analyses/
│       └── 1_MonteCarlo_RR.ipynb
├── 4_Hernan-Robins/
│   ├── Chapter-12.ipynb
│   ├── Chapter-13.ipynb
│   ├── Chapter-14.ipynb
│   ├── Data/
│   │   ├── NHEFS.xls
│   │   └── nhefs.csv
│   └── README.md
├── 5_Random_Demonstrations/
│   ├── Bayesian_Priors.ipynb
│   ├── Funk_2011_replication/
│   │   ├── aipw_example_python.ipynb
│   │   ├── aipw_example_r.R
│   │   ├── aipw_example_sas.sas
│   │   ├── dgm.py
│   │   ├── dr_data.csv
│   │   ├── funk_sim_rep.py
│   │   └── sim_results.md
│   ├── Model-Misspecification.ipynb
│   ├── Monty_Hall_Example.ipynb
│   ├── Super_Learner_Demonstration.ipynb
│   ├── Survey-Weights.ipynb
│   ├── Survivor_Bias.ipynb
│   └── stg_examples.py
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.ipynb_checkpoints
.idea


================================================
FILE: 1_Python-Basics/intro_to_python.ipynb
================================================
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to Python\n",
    "Here I will provide a basic introduction to Python 3.5+. We will review the variable types in Python and some basic functionalities. For learning more about Python, I recommend finding other tutorials. The main purpose of this tutorial is to provide a brief introduction to Python and serve as a refresher for basic functionalities. There are much better introductions than mine. My efforts in these tutorials primarly focus on conducting epidemiology analyses, which are downstream of basic Python functionalities (although necessary). \n",
    "\n",
    "Some other sources I would recommend for introductions are;\n",
    "\n",
    "https://learnxinyminutes.com/docs/python3/\n",
    "\n",
    "https://realpython.com/python-first-steps/\n",
    "\n",
    "https://nbviewer.jupyter.org/gist/anonymous/5924718\n",
    "\n",
    "Last edit: 2019/1/30\n",
    "\n",
    "## Print\n",
    "First we will start with the staple of the first line written in a new software, hello world. To print objects to the console, we use the ``print`` function. Additionally, note that anything following a ``#`` will not be run. These are comments, exactly like R's ``#`` and SAS's ``*;``"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World\n"
     ]
    }
   ],
   "source": [
    "print('Hello World') #Everything afterwards is considered a comment\n",
    "# print('I won't print since I am a comment')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Object types\n",
    "There four basic data types in Python; integers, floats, boolean, and strings. Integers are whole numbers, floats are decimals, boolean is True/False, and strings are text. Below is as example of each and the correspond type. We can use the ``type`` function to ask Python to identify the correspond object's type. This can be a useful function when you need a certain data type for functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'int'>\n",
      "<class 'float'>\n",
      "<class 'bool'>\n",
      "<class 'str'>\n"
     ]
    }
   ],
   "source": [
    "x = 2 #integer\n",
    "print(type(x))\n",
    "\n",
    "y = 0.3 #float\n",
    "print(type(y))\n",
    "\n",
    "q = True #Boolean\n",
    "print(type(q))\n",
    "\n",
    "z = 'two' #string\n",
    "print(type(z))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Additionally, you can convert between types, like converting floats to integers. Below are some examples of this"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "4.0\n",
      "2\n",
      "True\n",
      "0.0\n"
     ]
    }
   ],
   "source": [
    "# float -> int\n",
    "print(int(1.9))\n",
    "\n",
    "# int -> float\n",
    "print(float(4))\n",
    "\n",
    "# str -> int\n",
    "print(int('2'))\n",
    "\n",
    "# int -> bool\n",
    "print(bool(1))\n",
    "\n",
    "# bool -> int -> float\n",
    "print(float(int(False)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One important item to note is that ``bool`` converts any number besides zero to True. For example, converting 2 to a boolean returns ``True``. The same is true for -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(bool(2))\n",
    "print(bool(-1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Containers\n",
    "We can store multiple objects together in a container. I will review lists, sets, tuples, and dictionaries. For indexing, Python starts with ``0``. That mean the first item is in the ``0`` position according to Python. While this may seem weird and take time to get use to, it has some nice features. Notably, you can easily extract the last item in a list easily. Rather than counting up how long the list is then indexing that value, we instead index the ``-1`` item. Similarly the second last item is ``-2``. \n",
    "\n",
    "### Lists\n",
    "Lists are exactly what they sound like, a list of objects. Lists are mutable, meaning that we can edit the items inside a list. For example, let's say you create a list and mistyped the first item. You can edit the list rather than rewriting it\n",
    "\n",
    "Below we will create a list, do some indexing, adding an item to the end of the list, and then change the second item in the list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'list'>\n",
      "first\n",
      "last\n",
      "['first', 1, 1, 2, 3, 4, 5, 8, 8, 'last', 'add to list']\n",
      "['first', 'second', 1, 2, 3, 4, 5, 8, 8, 'last', 'add to list']\n"
     ]
    }
   ],
   "source": [
    "# Creating list\n",
    "l = ['first',1,1,2,3,4,5,8,8,'last']\n",
    "\n",
    "# Printing the type\n",
    "print(type(l))\n",
    "\n",
    "# Index the first item in the list\n",
    "print(l[0])\n",
    "\n",
    "# Index the last item in the list\n",
    "print(l[-1])\n",
    "\n",
    "# Adding item to the end of a list\n",
    "l.append('add to list')\n",
    "print(l)\n",
    "\n",
    "# Changing second item in list from 1 to 'second'\n",
    "l[1] = 'second'\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Sets\n",
    "Sets are an alternative container type. Unlike a list, sets are immutable and only contain unique values. Immutability is a nice feature if you want to prevent mistakenly changing your list. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4, 5, 'second', 8, 'first', 'add to list', 'last'}\n"
     ]
    }
   ],
   "source": [
    "s = set(l)\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you may notice, our set is different from the list (there is only one unique value for each item in our list). So, an easy way to see how many unique items are in a list, is to convert it to a set\n",
    "\n",
    "To show that sets are immutable, let's try to edit a set (we can't)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'set' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-12-2ff91758f384>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'new_value'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'set' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "s[3] = 'new_value'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see we get a ``TypeError``. The error tells us that we cannot assign a new value to a set. This is the immutable property in action\n",
    "\n",
    "### Tuples\n",
    "The next type of containers are tuples. Similar to sets, tuples are immutable. However, tuples allow for multiple duplicate items. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('first', 'second', 1, 2, 3, 4, 5, 8, 8, 'last', 'add to list')\n"
     ]
    }
   ],
   "source": [
    "t = tuple(l)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Again, let's demonstrate the immutability for tuples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-14-dcbd7316ac73>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mt\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'new_value'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "t[3] = 'new_value'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Dictionary\n",
    "The last container type I will outline is a dictionary. A dictionary is a paired list of keys and values. Unlike a list, there are specific pairs. This is useful if you have an informative key-value, instead of using indexes. Let's look at an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'zero': 0, 'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}\n"
     ]
    }
   ],
   "source": [
    "d = {'zero':0,'one':1,'two':2,\n",
    "     'three': 3, 'four':4}\n",
    "d['five'] = 5\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We created a dictionary linking string of words to the respective integers. We also added a pair to our dictionary (``'five':5``). The strings are referred to as ``keys`` and the corresponds integers are ``values`` in our dictionary. You can access either of those attributes like the following"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['zero', 'one', 'two', 'three', 'four', 'five'])\n",
      "dict_values([0, 1, 2, 3, 4, 5])\n"
     ]
    }
   ],
   "source": [
    "print(d.keys())\n",
    "print(d.values())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To index our dictionary, we provide the dictionary object the key we are interested in, like the following"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d['three']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Mathematical Operations\n",
    "We will now demonstrate some basic mathematical operations with Python. Python is a great calculator and I often use base Python instead of the calculator that comes with the OS. Below are some basic operations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "13\n",
      "-3\n",
      "40\n",
      "0.625\n",
      "390625\n",
      "0\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "print(5+8)  # addition\n",
    "print(5-8)  # subtraction\n",
    "print(5*8)  # multiplication\n",
    "print(5/8)  # division\n",
    "print(5**8)  # exponential\n",
    "print(5//8)  # returns only integer for division\n",
    "print(5%8)  # outputs remainder from division"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While we can use exponentials do calculate roots, there are more complicated operations we might want to do. For other mathematical operations, you can use the ``math`` library that comes with Python. To use ``math``, we need to import it. We do this by using the import statement. Additionally, when we want to use functions within the ``math`` library, we need to explicitly call that library. This behavior is different from R, which allows you to call functions within a library without having to call that library. \n",
    "\n",
    "In this example, we will load ``math`` and use it to calculate square root, natural log, exponentiate, and factorial"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0\n",
      "1.3862943611198906\n",
      "54.598150033144236\n",
      "24\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "print(math.sqrt(4))  # square root\n",
    "print(math.log(4))  # natural log \n",
    "print(math.exp(4))  # exponentiate (e^x)\n",
    "print(math.factorial(4))  # factorial"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Operation on Strings\n",
    "For this I will review a few operations on strings that can be done. We will discuss spacing, addition, and multiplication of strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Helloworld!\n",
      "\tHello\n",
      "new\n",
      "line\n",
      "repeat repeat repeat repeat repeat \n"
     ]
    }
   ],
   "source": [
    "print('Hello'+'world!')  # adding strings\n",
    "print('\\tHello')  # adding a tab. Uses \\t as keyword\n",
    "print('new'+'\\n'+'line')  # forcing a new line in the output. Uses \\n as keyword\n",
    "print('repeat '*5)  # multiplying a string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loops, conditional statements, and functions\n",
    "In this section, we will review how to construct loops, conditional statements, and create your own functions\n",
    "\n",
    "### Loops\n",
    "Loops are a way to go through each item of a container of items. To start out, we will create a ``for`` loop that prints every number from 0 to 4. For this loop, we will use the ``range`` function. When given a single number, the range function counts from 0 to that number. ``range`` is a helpful function for creating loops. Let's look at the example "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "for i in range(5):\n",
    "    print(i)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Our ``for`` loop counted each item in the range. \n",
    "\n",
    "Another type of loop is the ``while`` loop. This loop keeps executing until the ``while`` condition is satisified. Let's look at an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "0.5\n",
      "1.0\n",
      "1.5\n",
      "2.0\n",
      "2.5\n",
      "3.0\n",
      "3.5\n",
      "4.0\n",
      "4.5\n"
     ]
    }
   ],
   "source": [
    "i = 0\n",
    "while i < 5:\n",
    "    print(i)\n",
    "    i += 0.5\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note, we had to add to ``i`` in each execution of the loop. If we didn't we would get stuck in an infinite loop. When using a ``while`` loop be careful you don't accidentantly trap yourself in an infinite loop! There is no escape\n",
    "\n",
    "### Conditional statements\n",
    "As you are likely accustomed to, Python uses ``if`` statements. We can chain multiple statements together using ``if`` with ``elif`` (meaning else-if) and ``else`` (done if none of the previous is true). Let's talk the syntax of Python's conditional statements. First, you set up the ``if`` statement. If we want see whether two numbers are equal, we use ``a == b``. The ``if`` line then ends with a colon. All statements we want executed if that statement is true, are indented (4 spaces) underneath the ``if`` statement. Let's use an example to make this clear\n",
    "\n",
    "In this example, we will use a conditional statement to tell us where a specific number is 4 or 5. If it is neither of those numbers, the code will not print anything. We will look at `n` which we set equal to 4. Our first if-then statments looks to see if n is equal to 5. If true, then it tells us the number is five and print \"Hello\". Else-if the number is four, it tells us the number is four. If neither of the above is true, then Python does not return anything"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The current number is four\n"
     ]
    }
   ],
   "source": [
    "n = 4\n",
    "if n == 5:  # if n is equal to 5, then execute the below statements\n",
    "    print('The current number is five')\n",
    "    print('Hello')\n",
    "elif n == 4:  # else-if n is equal to 5, then execute the below statements\n",
    "    print('The current number is four')\n",
    "else:  # otherwise, execute the below statements\n",
    "    pass  # pass is a keyword that skips this line"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Try experimenting with the above code on your own! \n",
    "\n",
    "### Functions\n",
    "Functions are series of operations that can be linked together in one chunk of code. It makes it easy to run a calcuation multiple times or with different numbers. Every library uses functions (or classes) to allow you to perform operations. In this example, we will go over how to create your own function to use in your code.\n",
    "\n",
    "For our example, we will create a function to calculate the risk ratio. The first line begins with 'def' which stands for define. next we provide a function name. We call ours 'risk_ratio'. Next are the paratheses containing the input variables. Our function has four required variables. The inputs designated `a`, `b`, `c`, and `d`. Without them, our function will produce an error. Note that everything below is indented. This tells Python what is included in a function. \n",
    "\n",
    "Next part of the function is documentation. This is to help us remember what this function is used for. When writing this section, be as detailed as possible. How would you improve the documentation? We can view the functions documentation by running help(risk_ratio). This is helpful when trying to see what argument options are available for a function. \n",
    "\n",
    "Lastly, we have a series of statements that our function executes when called. Our function only calculates the risk ratio if all inputs are postive numbers (or zero). We also use `return`, which returns the value calculated. So if we set `x = risk_ratio(...)`, `x` will be set equal to `rr` from our function.\n",
    "\n",
    "Let's dive in"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "def risk_ratio(a, b, c, d):\n",
    "    '''You can add function documentation underneath 'def' statement in triple quotes.\n",
    "    I highly recommend adding documentation in your own code\n",
    "    \n",
    "    This function calculates the Risk Ratio. The inputs are the numbers from a 2x2 table.\n",
    "    All numbers must be positive, otherwise a ValueError will be raised\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    a:\n",
    "        exposed and had the outcome\n",
    "    b:\n",
    "        exposed and did not have the outcome\n",
    "    c:\n",
    "        unexposed and had the outcome\n",
    "    d:\n",
    "        unexposed and did not have the outcome\n",
    "    '''\n",
    "    if a < 0 or b < 0 or c < 0 or d < 0:\n",
    "        raise ValueError('All inputs must be positive')\n",
    "    risk_e = a / (a+b)\n",
    "    risk_u = c / (c+d)\n",
    "    rr = risk_e / risk_u\n",
    "    return rr\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have our function specified, let's try it out!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RR = 1.8888888888888886\n",
      "RR = 0.9068462401795735\n"
     ]
    }
   ],
   "source": [
    "rratio1 = risk_ratio(5, 10, 3, 14)\n",
    "print('RR =', rratio1)\n",
    "\n",
    "rratio2 = risk_ratio(8, 25, 27, 74)\n",
    "print('RR =', rratio2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That concludes the Python tutorial. This is only a brief outline and is meant as a refresher for Python"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}


================================================
FILE: 2_Data-Basics/1_data_management.ipynb
================================================
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to Data Management\n",
    "i.e. introduction to `numpy` and `pandas`\n",
    "\n",
    "Now that we have a handle on the basics of Python 3.x syntax, let's start doing some data manipulation. The two most important packages we will be using are NumPy and Pandas. NumPy contains loads of useful functions and improved storage objects, like matrices (think improved lists) and functions that produce various calculations. Pandas is built on top of NumPy and allows traditional data storage, display, and tools. Like all of our code, we begin with importing the relevant packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you may already know, the ``import ... as ...`` functionality allows us to import a package and refer to it as a shorter name. It is common practice to abbreviate `numpy` as `np` and `pandas` as `pd`. In your code, *never* set variables to have these names (unless you really want to give yourself a headache)\n",
    "\n",
    "## Missing Data\n",
    "Unlike most python data science intros, I am going to start with missing data. Missing data is a common issue in an epidemiologist's data sets. Simply ignoring missing data and how `numpy` and `pandas` handle missing data is only going to cause later trouble for us. So, how does Python handle missing data?\n",
    "\n",
    "Since Python was original meant as a computer programming language, missing data is a little awkward. The `math` library allows for missing data with `nan`. More commonly you will use `np.nan`. `nan` has some properties that may be surprising. `nan` will never evaluate to be equal to `nan`. Let's look at an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.nan == np.nan"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Weird... but why does this matter? For any data manipulation operations with missing data in a column, you will need to keep this in mind. Expecting something to be equal to `nan` won't evaluate to be true. Instead, you will need to use special `numpy` or `pandas` functions like `isnan()`. For example,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(np.isnan(np.nan))\n",
    "print(pd.isnull(np.nan))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So remember, **nan is not equal to nan**\n",
    "\n",
    "The next item to highlight is a `pandas` behavior. When you have a column with `int` data that has missing values, it will be stored as a `float` type. This does not lead to any major issues, but if you *need* a column to be of `int` type, know that there can be no missing data. No matter how hard you try to change the type to `int`, it will remain `float`. If you absolutely need that column to be `int`, then you will need to remove the `nan`'s (or give them some dummy integer value). You will likely never need a column to absolutely have to be `int` though\n",
    "\n",
    "## Loading Data\n",
    "This next section details reading in data from outside file formats.\n",
    "\n",
    "### CSV \n",
    "Let's review how to read in CSV files. CSV stands for \"comma separated values\". I have put a sample CSV file in this tutorial folder labeled `sample_csv.csv`. To load this data file using pandas, we use the `read_csv()` function. Let's look at an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 100000 entries, 0 to 99999\n",
      "Data columns (total 9 columns):\n",
      "A         100000 non-null int64\n",
      "L         100000 non-null float64\n",
      "B_true    100000 non-null int64\n",
      "C_true    100000 non-null int64\n",
      "M2        100000 non-null int64\n",
      "M3        100000 non-null int64\n",
      "B         87168 non-null float64\n",
      "C         27432 non-null float64\n",
      "id        100000 non-null int64\n",
      "dtypes: float64(3), int64(6)\n",
      "memory usage: 6.9 MB\n"
     ]
    }
   ],
   "source": [
    "# If CSV is in the same folder as your Python program\n",
    "df = pd.read_csv('sample_csv.csv')\n",
    "df.info()\n",
    "\n",
    "# Explicit path to file\n",
    "# df = pd.read_csv('C:/file/path/to/sample_csv.csv')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`read_csv()` has lots of options to help with reading in your data. You can set the column names, skip certain rows/columns, and much more. I recommend reviewing the `pandas` documentation for further details (*hint* try searching for \"pandas read_csv\" in your search engine of choice)\n",
    "\n",
    "### DAT\n",
    "`.dat` files are a more universal format you may run in to. They have a wider option of what are referred to as delimiters. Delimiters mark where a particular cell/column ends. Another common delimiter is tabs (known as tab-delimited files). I have another file of example data labelled as `sample_tab.dat`. Let's read that in that data.\n",
    "\n",
    "We will use a few different options. Our input data does not have an index, so we set `index_col=False`. Additionally, our data set does not have column labels, so we set `header=None` to prevent our first line of data from becoming the column labels. We can manually create those by passing in the `names` option. We set `names` to be equal to our list of column labels. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 27382 entries, 0 to 27381\n",
      "Data columns (total 12 columns):\n",
      "id       27382 non-null int64\n",
      "enter    27382 non-null int64\n",
      "out      27382 non-null float64\n",
      "male     27382 non-null int64\n",
      "age0     27382 non-null int64\n",
      "cd40     27382 non-null int64\n",
      "dvl0     27382 non-null int64\n",
      "cd4      27382 non-null int64\n",
      "dvl      27382 non-null int64\n",
      "art      27382 non-null int64\n",
      "drop     27382 non-null int64\n",
      "dead     27382 non-null int64\n",
      "dtypes: float64(1), int64(11)\n",
      "memory usage: 2.5 MB\n"
     ]
    }
   ],
   "source": [
    "cols = ['id', 'enter', 'out', 'male', 'age0', 'cd40', 'dvl0', 'cd4', 'dvl', 'art', 'drop', 'dead']\n",
    "\n",
    "# tab-delimited DAT file\n",
    "df = pd.read_csv('sample_dat.dat', delim_whitespace=True, header=None, names=cols, index_col=False)\n",
    "df.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So, `read_csv()` is much more than only CSV files. \n",
    "\n",
    "### SAS7BDAT\n",
    "Since I sometimes have to load in SAS data files, let's go through an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 547 entries, 0 to 546\n",
      "Data columns (total 8 columns):\n",
      "id      547 non-null float64\n",
      "male    547 non-null float64\n",
      "age0    547 non-null float64\n",
      "cd40    547 non-null float64\n",
      "dvl0    547 non-null float64\n",
      "art     547 non-null float64\n",
      "dead    517 non-null float64\n",
      "t       547 non-null float64\n",
      "dtypes: float64(8)\n",
      "memory usage: 34.3 KB\n"
     ]
    }
   ],
   "source": [
    "df = pd.read_sas('sample_sas.sas7bdat')\n",
    "df.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will use the SAS file for the remainder of the data management tutorial\n",
    "\n",
    "### Other File Formats\n",
    "Python supports a wide variety of formats. I have only reviewed popular formats here. If you are having trouble reading in a specific file format that I have not described, I recommend searching the `pandas` documents for help. \n",
    "\n",
    "## Basic Data Set Info\n",
    "Now that our data set is loaded, let's take a look at some basic features. Once our `pandas` `DataFrame` is loaded, it gains a few functions. \n",
    "\n",
    "The first is `info()` which provides the observation count and variable types. `info()` always prints to the console, so it does not need to be wrapped in a print statement.\n",
    "\n",
    "Next is `head(5)` which will print out the first five observations. We can change the number of observations printed by changing the number\n",
    "\n",
    "Next is `tail(3)` which will print out the last three observations. Similarly, we can change the number to change how many observations are printed\n",
    "\n",
    "Last is `describe()` which provides summary stats for each column in the data frame with numeric data. This is a great way to get a general idea of distributions of variables in your data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 547 entries, 0 to 546\n",
      "Data columns (total 8 columns):\n",
      "id      547 non-null float64\n",
      "male    547 non-null float64\n",
      "age0    547 non-null float64\n",
      "cd40    547 non-null float64\n",
      "dvl0    547 non-null float64\n",
      "art     547 non-null float64\n",
      "dead    517 non-null float64\n",
      "t       547 non-null float64\n",
      "dtypes: float64(8)\n",
      "memory usage: 34.3 KB\n",
      "First observations:\n",
      "     id  male  age0   cd40  dvl0  art  dead       t\n",
      "0  2.0   1.0  51.0  440.0   1.0  0.0   1.0  32.043\n",
      "1  3.0   1.0  21.0  219.0   0.0  0.0   0.0  60.000\n",
      "2  5.0   1.0  18.0  460.0   0.0  0.0   0.0  60.000\n",
      "3  6.0   1.0  34.0  470.0   1.0  0.0   0.0  60.000\n",
      "4  7.0   1.0  29.0  361.0   0.0  0.0   0.0  60.000\n",
      "5  8.0   1.0  45.0    4.0   1.0  0.0   0.0  60.000\n",
      "Last observations:\n",
      "         id  male  age0   cd40  dvl0  art  dead     t\n",
      "542  795.0   0.0  20.0  494.0   1.0  0.0   0.0  60.0\n",
      "543  796.0   1.0  33.0  458.0   1.0  0.0   0.0  60.0\n",
      "544  798.0   1.0  32.0  237.0   1.0  0.0   0.0  60.0\n",
      "545  799.0   1.0  44.0  488.0   1.0  0.0   0.0  60.0\n",
      "546  800.0   0.0  40.0  209.0   0.0  0.0   0.0  60.0\n",
      "Basic Descriptives:\n",
      "                id        male        age0        cd40        dvl0         art  \\\n",
      "count  547.000000  547.000000  547.000000  547.000000  547.000000  547.000000   \n",
      "mean   400.054845    0.815356   38.519196  303.301645    0.890311    0.144424   \n",
      "std    234.087576    0.388363    9.642183  134.033586    0.312788    0.351841   \n",
      "min      2.000000    0.000000   18.000000    1.000000    0.000000    0.000000   \n",
      "25%    188.000000    1.000000   32.000000  220.500000    1.000000    0.000000   \n",
      "50%    402.000000    1.000000   39.000000  326.000000    1.000000    0.000000   \n",
      "75%    605.500000    1.000000   46.000000  415.500000    1.000000    0.000000   \n",
      "max    800.000000    1.000000   63.000000  500.000000    1.000000    1.000000   \n",
      "\n",
      "             dead           t  \n",
      "count  517.000000  547.000000  \n",
      "mean     0.168279   49.934563  \n",
      "std      0.374476   19.521671  \n",
      "min      0.000000    0.055000  \n",
      "25%      0.000000   57.104000  \n",
      "50%      0.000000   60.000000  \n",
      "75%      0.000000   60.000000  \n",
      "max      1.000000   60.000000  \n"
     ]
    }
   ],
   "source": [
    "# Basic meta-data summary\n",
    "df.info()\n",
    "\n",
    "# print the first 6 observations\n",
    "print('First observations:\\n', df.head(6))\n",
    "\n",
    "# print the last 5 observations\n",
    "print('Last observations:\\n', df.tail(5))\n",
    "\n",
    "# print basic descriptives of numeric columns\n",
    "print('Basic Descriptives:\\n', df.describe())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also access the list of all the columns in your data set by `print(df.columns())`. I will leave this for you to try on your own.\n",
    "\n",
    "## Selecting / Subsetting Data\n",
    "Now that we have the basic set up of our data frame, let's go over how to select columns and rows\n",
    "\n",
    "### Column Selection\n",
    "For various purposes, we might only want to select a single column. To index a column, you use the following code `df['column_label']` where `column_label` refers to your column label. For our example, we only want to look at the first 3 observations of the `art` column. To do that we can use the following "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    0.0\n",
      "1    0.0\n",
      "2    0.0\n",
      "Name: art, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "print(df['art'].head(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There is an alternative to selecting columns and that is to use `df.column_label`. Beware of this option. It is less clear, your column name might overlap with a `pandas` function, it cannot handle multiple columns, and it cannot handle spaces (if they exist in your column labels). I would recommend using `df['column_label']`. I mention the other option since you might come across it in the wild (I sometime use it despite my own advice)\n",
    "\n",
    "To select multiple columns, we can instead provide a list of columns. Below is an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     art  dead\n",
      "542  0.0   0.0\n",
      "543  0.0   0.0\n",
      "544  0.0   0.0\n",
      "545  0.0   0.0\n",
      "546  0.0   0.0\n",
      "     art  dead\n",
      "545  0.0   0.0\n",
      "546  0.0   0.0\n"
     ]
    }
   ],
   "source": [
    "# Multiple column selection in one-line\n",
    "print(df[['art', 'dead']].tail(5))\n",
    "\n",
    "# Multiple column selection emphasizing the use of a list of column names\n",
    "columns_to_select = ['art', 'dead']\n",
    "print(df[columns_to_select].tail(2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have some column selection basics, let's detail three specific `pandas` operations before moving on; `unique()`, `value_counts()`, and `crosstab`. \n",
    "\n",
    "`unique()` returns all the unique values contained in a column. \n",
    "\n",
    "`value_counts()` is an extension of unique that provides the unique values in a column but also their frequency\n",
    "\n",
    "`crosstab()` creates a crosstabulation of two or more columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Unique values: [0. 1.]\n",
      "\n",
      "Counts of unique values:\n",
      " 0.0    468\n",
      "1.0     79\n",
      "Name: art, dtype: int64\n",
      "\n",
      "N-by-M table:\n",
      " dead  0.0  1.0\n",
      "art           \n",
      "0.0   363   77\n",
      "1.0    67   10\n"
     ]
    }
   ],
   "source": [
    "# All unique values in a column\n",
    "print('Unique values:', df['art'].unique())\n",
    "\n",
    "# Unique values and their frequency in a column\n",
    "print('\\nCounts of unique values:\\n', df['art'].value_counts())\n",
    "\n",
    "# Crosstabulation of two variables\n",
    "print('\\nN-by-M table:\\n', pd.crosstab(df['art'], df['dead']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That concludes the basics of column selection / subsetting from a data set\n",
    "\n",
    "### Row Selection\n",
    "Now let's go over the basics of row selection. Let's start by selection all the rows in the data set where ART is given (`art=1`) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        id  male  age0   cd40  dvl0  art  dead       t\n",
      "15    28.0   0.0  49.0  226.0   1.0  1.0   0.0  60.000\n",
      "16    29.0   0.0  47.0  332.0   1.0  1.0   0.0  60.000\n",
      "19    32.0   1.0  49.0  413.0   1.0  1.0   0.0  60.000\n",
      "25    39.0   1.0  36.0  424.0   1.0  1.0   0.0  60.000\n",
      "29    45.0   1.0  39.0  274.0   1.0  1.0   0.0  60.000\n",
      "35    52.0   1.0  44.0  309.0   0.0  1.0   0.0  60.000\n",
      "36    54.0   1.0  48.0  192.0   1.0  1.0   0.0  60.000\n",
      "46    70.0   1.0  39.0  126.0   1.0  1.0   0.0  60.000\n",
      "82   114.0   1.0  40.0  123.0   1.0  1.0   0.0  60.000\n",
      "86   119.0   1.0  41.0  391.0   1.0  1.0   0.0  60.000\n",
      "93   127.0   1.0  37.0  408.0   1.0  1.0   0.0  60.000\n",
      "98   134.0   0.0  41.0  345.0   1.0  1.0   0.0  60.000\n",
      "111  155.0   1.0  44.0  139.0   1.0  1.0   0.0  60.000\n",
      "113  158.0   1.0  29.0  216.0   1.0  1.0   0.0  60.000\n",
      "130  180.0   1.0  62.0  204.0   1.0  1.0   0.0  60.000\n",
      "136  187.0   1.0  40.0   90.0   1.0  1.0   1.0   0.094\n",
      "137  189.0   1.0  54.0  301.0   1.0  1.0   0.0  60.000\n",
      "141  197.0   1.0  19.0  224.0   1.0  1.0   0.0  60.000\n",
      "143  201.0   1.0  50.0  381.0   0.0  1.0   0.0  60.000\n",
      "148  211.0   1.0  43.0   47.0   1.0  1.0   0.0  60.000\n",
      "150  214.0   1.0  32.0  215.0   0.0  1.0   1.0   0.974\n",
      "158  228.0   1.0  50.0   83.0   1.0  1.0   1.0   4.491\n",
      "160  231.0   1.0  40.0  128.0   1.0  1.0   0.0  60.000\n",
      "161  232.0   1.0  52.0  462.0   1.0  1.0   0.0  60.000\n",
      "167  240.0   1.0  47.0  352.0   1.0  1.0   NaN  12.734\n",
      "170  243.0   1.0  38.0  192.0   1.0  1.0   0.0  60.000\n",
      "175  249.0   0.0  51.0  421.0   1.0  1.0   0.0  60.000\n",
      "178  253.0   1.0  36.0  278.0   1.0  1.0   0.0  60.000\n",
      "187  269.0   0.0  45.0  417.0   1.0  1.0   1.0   1.389\n",
      "190  275.0   1.0  18.0  352.0   1.0  1.0   0.0  60.000\n",
      "..     ...   ...   ...    ...   ...  ...   ...     ...\n",
      "299  442.0   1.0  44.0  213.0   1.0  1.0   0.0  60.000\n",
      "317  471.0   1.0  35.0  156.0   0.0  1.0   0.0  51.769\n",
      "328  487.0   1.0  34.0   20.0   0.0  1.0   1.0   1.977\n",
      "339  504.0   1.0  48.0  236.0   0.0  1.0   0.0  60.000\n",
      "354  522.0   1.0  40.0  458.0   1.0  1.0   0.0  60.000\n",
      "355  524.0   1.0  32.0  152.0   1.0  1.0   0.0  60.000\n",
      "366  542.0   1.0  32.0  229.0   0.0  1.0   0.0  46.851\n",
      "377  562.0   1.0  42.0  461.0   1.0  1.0   0.0  60.000\n",
      "399  592.0   1.0  23.0  480.0   1.0  1.0   0.0  60.000\n",
      "404  598.0   0.0  35.0  430.0   1.0  1.0   0.0  60.000\n",
      "406  600.0   1.0  45.0  387.0   1.0  1.0   0.0  60.000\n",
      "418  618.0   1.0  40.0  309.0   1.0  1.0   0.0  60.000\n",
      "429  633.0   0.0  29.0  308.0   1.0  1.0   0.0  60.000\n",
      "443  650.0   0.0  29.0  115.0   1.0  1.0   0.0  60.000\n",
      "449  658.0   0.0  23.0  441.0   1.0  1.0   0.0  60.000\n",
      "454  666.0   1.0  48.0  123.0   0.0  1.0   0.0  60.000\n",
      "464  680.0   0.0  35.0  211.0   0.0  1.0   0.0  60.000\n",
      "468  685.0   0.0  36.0  237.0   1.0  1.0   0.0  60.000\n",
      "469  687.0   0.0  53.0  273.0   1.0  1.0   0.0  60.000\n",
      "474  695.0   1.0  29.0    2.0   1.0  1.0   1.0   2.646\n",
      "481  707.0   1.0  25.0  483.0   1.0  1.0   0.0  60.000\n",
      "483  709.0   1.0  43.0   37.0   1.0  1.0   1.0   4.490\n",
      "490  719.0   1.0  41.0  119.0   1.0  1.0   0.0  60.000\n",
      "498  730.0   1.0  18.0  248.0   1.0  1.0   1.0  10.654\n",
      "499  732.0   0.0  22.0  465.0   1.0  1.0   0.0  60.000\n",
      "524  768.0   1.0  31.0  321.0   1.0  1.0   0.0  60.000\n",
      "527  771.0   1.0  45.0   35.0   1.0  1.0   0.0  60.000\n",
      "529  774.0   1.0  59.0  460.0   1.0  1.0   0.0  60.000\n",
      "534  780.0   1.0  51.0  264.0   1.0  1.0   1.0   1.827\n",
      "541  792.0   1.0  25.0  282.0   1.0  1.0   0.0  60.000\n",
      "\n",
      "[79 rows x 8 columns]\n"
     ]
    }
   ],
   "source": [
    "print(df.loc[df['art']==1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So how did that work? There are two moving parts. First is the part inside the `.loc[...]` function. This section checks whether the condition is met for each row in that column. Pulling out that part results in "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0      False\n",
       "1      False\n",
       "2      False\n",
       "3      False\n",
       "4      False\n",
       "5      False\n",
       "6      False\n",
       "7      False\n",
       "8      False\n",
       "9      False\n",
       "10     False\n",
       "11     False\n",
       "12     False\n",
       "13     False\n",
       "14     False\n",
       "15      True\n",
       "16      True\n",
       "17     False\n",
       "18     False\n",
       "19      True\n",
       "20     False\n",
       "21     False\n",
       "22     False\n",
       "23     False\n",
       "24     False\n",
       "25      True\n",
       "26     False\n",
       "27     False\n",
       "28     False\n",
       "29      True\n",
       "       ...  \n",
       "517    False\n",
       "518    False\n",
       "519    False\n",
       "520    False\n",
       "521    False\n",
       "522    False\n",
       "523    False\n",
       "524     True\n",
       "525    False\n",
       "526    False\n",
       "527     True\n",
       "528    False\n",
       "529     True\n",
       "530    False\n",
       "531    False\n",
       "532    False\n",
       "533    False\n",
       "534     True\n",
       "535    False\n",
       "536    False\n",
       "537    False\n",
       "538    False\n",
       "539    False\n",
       "540    False\n",
       "541     True\n",
       "542    False\n",
       "543    False\n",
       "544    False\n",
       "545    False\n",
       "546    False\n",
       "Name: art, Length: 547, dtype: bool"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['art']==1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A Series of `True` and `False` where the conditions are met or not met, respectively. Then our `.loc` function takes this series of True and False and subsets only the rows where True occurs. \n",
    "\n",
    "Let's take a look at selecting columns based on two conditions. We will select only those who received ART and are above age 48"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        id  male  age0   cd40  dvl0  art  dead       t\n",
      "15    28.0   0.0  49.0  226.0   1.0  1.0   0.0  60.000\n",
      "19    32.0   1.0  49.0  413.0   1.0  1.0   0.0  60.000\n",
      "130  180.0   1.0  62.0  204.0   1.0  1.0   0.0  60.000\n",
      "137  189.0   1.0  54.0  301.0   1.0  1.0   0.0  60.000\n",
      "143  201.0   1.0  50.0  381.0   0.0  1.0   0.0  60.000\n",
      "158  228.0   1.0  50.0   83.0   1.0  1.0   1.0   4.491\n",
      "161  232.0   1.0  52.0  462.0   1.0  1.0   0.0  60.000\n",
      "175  249.0   0.0  51.0  421.0   1.0  1.0   0.0  60.000\n",
      "191  276.0   1.0  57.0  326.0   1.0  1.0   0.0  60.000\n",
      "199  284.0   1.0  49.0  131.0   1.0  1.0   0.0  60.000\n",
      "238  346.0   1.0  51.0  338.0   1.0  1.0   0.0  60.000\n",
      "241  353.0   1.0  51.0   68.0   1.0  1.0   0.0  60.000\n",
      "469  687.0   0.0  53.0  273.0   1.0  1.0   0.0  60.000\n",
      "529  774.0   1.0  59.0  460.0   1.0  1.0   0.0  60.000\n",
      "534  780.0   1.0  51.0  264.0   1.0  1.0   1.0   1.827\n"
     ]
    }
   ],
   "source": [
    "print(df.loc[(df['art'] == 1) & (df['age0'] > 48)])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the inside of the `.loc[...]` follows the standard order of operations. To link multiple conditions together `&` means \"and\", `|` means \"inclusive or\", and `^` is the \"exclusive or\". As a reminder the inclusive or requires that at least one is True, while exclusive or requires that only one is True. \n",
    "\n",
    "Finally, note the parenthenses. If each individual evaluation is not wrapped in a parenthesis, then the conditional will not evaluate. Without the parentheses you will get a `ValueError`\n",
    "\n",
    "#### Side Note:\n",
    "While you may be tempted to use `and` and `or` instead, these operators don't deal with NumPy and Pandas too well. It is better to use `&` and `|`.\n",
    "\n",
    "### Column and Row Selection\n",
    "We now can merge our column and row selection together. To motivate our problem, we are interested in looking at the CD4 T-cell counts by treatment status. Let's look at how we can do this."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15     226.0\n",
      "16     332.0\n",
      "19     413.0\n",
      "25     424.0\n",
      "29     274.0\n",
      "35     309.0\n",
      "36     192.0\n",
      "46     126.0\n",
      "82     123.0\n",
      "86     391.0\n",
      "93     408.0\n",
      "98     345.0\n",
      "111    139.0\n",
      "113    216.0\n",
      "130    204.0\n",
      "136     90.0\n",
      "137    301.0\n",
      "141    224.0\n",
      "143    381.0\n",
      "148     47.0\n",
      "150    215.0\n",
      "158     83.0\n",
      "160    128.0\n",
      "161    462.0\n",
      "167    352.0\n",
      "170    192.0\n",
      "175    421.0\n",
      "178    278.0\n",
      "187    417.0\n",
      "190    352.0\n",
      "       ...  \n",
      "299    213.0\n",
      "317    156.0\n",
      "328     20.0\n",
      "339    236.0\n",
      "354    458.0\n",
      "355    152.0\n",
      "366    229.0\n",
      "377    461.0\n",
      "399    480.0\n",
      "404    430.0\n",
      "406    387.0\n",
      "418    309.0\n",
      "429    308.0\n",
      "443    115.0\n",
      "449    441.0\n",
      "454    123.0\n",
      "464    211.0\n",
      "468    237.0\n",
      "469    273.0\n",
      "474      2.0\n",
      "481    483.0\n",
      "483     37.0\n",
      "490    119.0\n",
      "498    248.0\n",
      "499    465.0\n",
      "524    321.0\n",
      "527     35.0\n",
      "529    460.0\n",
      "534    264.0\n",
      "541    282.0\n",
      "Name: cd40, Length: 79, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "print(df.loc[df['art'] == 1, 'cd40'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As this example shows, you can use `.loc` to access both selected rows and columns, where the conditions are set up as follows `df.loc[row, column]`. \n",
    "\n",
    "As a demonstration, let's calculate the mean baseline CD4 T-cell count among those given ART with what we have learned and the NumPy function `mean()`. When I subset the data in this example, I will use the `copy()` function at the end. This will return a copy of the subset data. This is good practice to prevent accidentally overwritting something in your original data. Pandas will also generate a warning if you do not create a copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "247.13924050632912\n",
      "247.13924050632912\n"
     ]
    }
   ],
   "source": [
    "# Subsetting rows and the column of interest\n",
    "dfs = df.loc[df['art'] == 1, 'cd40'].copy()\n",
    "\n",
    "# calculating mean with numpy\n",
    "print(np.mean(dfs))\n",
    "\n",
    "# calculating mean with pandas\n",
    "print(dfs.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the above, I calculated the mean using two different approaches. One used `np.mean()` and the other used `pd.mean()`. These provide the same results (as would be expected). Often there are multiple ways to do things in Python. This is one example.\n",
    "\n",
    "Test yourself by trying to calculate the mean CD4 T-cell count among those not given ART.\n",
    "\n",
    "## Data Operations\n",
    "Now that we have the basics of row and column selection, it is time to introduce some data manipulation. Let's start changing the values of variables. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a new column that is a copy of another variable\n",
    "df['art_copy'] = df['art']\n",
    "\n",
    "# Adding constant to a column\n",
    "df['cd4_plus5'] = df['cd40'] + 5\n",
    "\n",
    "# Dividing by constant from a column\n",
    "df['cd4_div12'] = df['cd40'] / 12\n",
    "\n",
    "# Squaring a column\n",
    "df['age_sq'] = df['age0']**2\n",
    "\n",
    "# Using numpy to get square root of column\n",
    "df['age_sqrt'] = np.sqrt(df['age0'])\n",
    "\n",
    "# Adding two columns together\n",
    "df['age_plus_cd4'] = df['age0'] + df['cd40']\n",
    "\n",
    "# Multiple operations\n",
    "df['weird_age'] = (df['age0']*0.5)**2 + (df['cd40']/1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These are just a few basic examples of operations. Note that these are applied to each row. What if we want to only perform operations on select rows?\n",
    "\n",
    "### Recoding\n",
    "For the purposes of the tutorial, let's say we were concerned about outliers in age. To remove the outliers, we wanted to set everyone older than 50 to 50. How can we do that? I will go through two different approaches\n",
    "\n",
    "#### np.where\n",
    "NumPy `where` is a special function that evaluates a conditional statement for us. Additionally we can use it to generate new numbers. In `np.where(a, b, c)`, `a` is the condition we want to evaluate, `b` is the value given when the condition is True, and `c` is the value when the condition is False.\n",
    "\n",
    "Going to our example, we can to find all those older than 50 (`df['age0'] > 50`) and set them equal to 50 (`50`). Otherwise, we want that row to retain its observed value (`df['age0']`). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "50.0\n"
     ]
    }
   ],
   "source": [
    "# using np.where\n",
    "df['age2_numpy'] = np.where(df['age0'] > 50,  # condition\n",
    "                           50,  # when condition is True\n",
    "                           df['age0'])  # when condition if False\n",
    "\n",
    "print(np.max(df['age2_numpy']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see, the new maximum age is 50, just as our recoding wants. \n",
    "\n",
    "#### df.loc\n",
    "An alternative is to use our friend `loc[...]` to help us out. Using the column selector, we can create a new column and update values. Below is an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "50.0\n"
     ]
    }
   ],
   "source": [
    "df.loc[df['age0'] > 50, 'age2_pandas'] = 50\n",
    "df.loc[df['age0'] <= 50, 'age2_pandas'] = df['age0']\n",
    "\n",
    "print(np.max(df['age2_pandas']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These two approaches give the same results. Personally, I like `np.where` but use whatever you prefer. \n",
    "\n",
    "For practice, try making a new age variable where age is squared when between 25 to 45. Otherwise it should be equal to age. You will need what you learned in this section and the row/column selection section to do this. If you have trouble, try going back through the tutorials or open an Issue on my GitHub page\n",
    "\n",
    "## Saving Data\n",
    "Now that you have done all that work, let's save the data. Python does not automatically save your data. You will need to save it as a new file (or overwrite your old one. do **not** recommend this though). To do that, we can use the handy pandas function `to_csv`. This function will have our DataFrame as a CSV. \n",
    "\n",
    "I set `index=False` to keep pandas from saving the index data to the CSV. I don't usually need it, but if you want to save the index, remove this optional argument"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.to_csv('saved_file.csv', index=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Aside\n",
    "Before concluding the tutorial, I wanted to return to missing data one more time. Now I will touch on a few unexpected behaviors that `np.nan` has\n",
    "\n",
    "`pd.crosstab` has what I think is an unusual behavior. If you look at the online documentation, you will see that it has the optional argument `dropna`. \"Awesome!\" you think, \"I will be able to easily see the missing data patterns in my data set\". Let's return to our previous crosstab usage, but set `dropna=False`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dead  0.0  1.0\n",
      "art           \n",
      "0.0   363   77\n",
      "1.0    67   10\n"
     ]
    }
   ],
   "source": [
    "print(pd.crosstab(df['art'], df['dead'], dropna=False))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That's weird... there is no missing data column. That's is because the `dropna` argument does not do what you are imagining it does. To see any missing data patterns, we can use `crosstab` but we have to pair it with something. I will use ``fillna()`` to fill in all the missing data points with `-99999`. When using this function to look at missing data patterns, make sure to a value that is not in your data!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dead  -99999.0   0.0       1.0    \n",
      "art                               \n",
      "0.0         28       363        77\n",
      "1.0          2        67        10\n"
     ]
    }
   ],
   "source": [
    "df.fillna(-99999, inplace=True)\n",
    "print(pd.crosstab(df['art'], df['dead']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can see the missing data pattern! It is generally easier to create a new dataframe with the `nan` filled in rather than using the `inplace` argument as I did. `inplace` means that I would need to use one of the data manipulation approaches to set `-99999` cells back to `nan`. However, this concludes our tutorial\n",
    "\n",
    "# Conclusion\n",
    "That concludes the basic tutorial of data manipulations with NumPy and Pandas. There is a lot I did not cover (handling datetimes, converting between long and wide data sets, mergining data sets, etc.). I will leave those for you to explore. The online documentation for Pandas is pretty great and StackOverflow has the answer to just about any Pandas question you could have. \n",
    "\n",
    "To really learn Pandas, I would recommend replicating some data cleaning you have previously done. I taught myself Pandas by replicating class assignments that I had original done in SAS. This approach allows you to check your answer with a correct one and it teaches you the overlap between functionalities in different softwares. It was about 3 months of doing data manipulation in Python (specifically with NumPy and pandas) that I became adept at it. Practice makes perfect"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}


================================================
FILE: 2_Data-Basics/2_intro_to_plots.ipynb
================================================
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Graphics in Python\n",
    "In this tutorial, I will go over some of the basics of how to generate graphs and plots using Python. I will describe the usage of `matplotlib`. I will only be reviewing some basics. The purpose is to provide a general idea of how `matplotlib` works, not detail every plotting function. The matplotlib website has great examples and detailed code on how to generate a variety of plots. I highly recommend viewing their documentation when trying to make your own plots (I still regularly refer to their docs)\n",
    "\n",
    "https://matplotlib.org/\n",
    "\n",
    "I also should mention `seaborn`. `seaborn` is a library that is an extension to `matplotlib`. It provides a simpler interface for some type of plots. For example, to make a scatter matrix in `matplotlib` requires a bit of data manipulation and different plot functions. `seaborn` can accomplish this with a single statement (with a variety of options). I recommend downloading `seaborn` and going through the documentation when creating your own plots. I will not detail `seaborn`, since I want to focus on the lower-level graphic interface. You can read more about `seaborn` here\n",
    "\n",
    "https://seaborn.pydata.org/\n",
    "\n",
    "## The Basics\n",
    "I will review some basic functionalities\n",
    "\n",
    "### Matplotlib Magic\n",
    "This section *only* applies to JuPyter Notebooks. Since this tutorial uses JuPyter Notebook, we can use \"matplotlib magic\" to have our plots display in-line. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Running that line ensures our plots will be displayed right below the code in our notebook. How the graphics generated by `matplotlib` are displayed differs by your IDE. Some IDE's like y-hat's Rodeo display plots in the IDE directly (like R Studio), while others like IDLE and PyCharm open a separate window with the plot. This latter behavior is also the same when running scripts in Command Prompt / Terminal\n",
    "\n",
    "### Creating a plot\n",
    "I will start with plotting a single point. We can do that by using `plot`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "plt.plot(1, 1, 'o')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So, let's break down that previous code. All the plotting functions I will describe are within `matplotlib.pyplot`, which we shorten to import as `plt`. Then we use the `plot()` function to add a single point. The first argument is the `x` values, and the second is the `y` values. Lastly, we have `'o'`, which tells `matplotlib` to plot points (the default is a line, which is not nothing for a single point). Finally, we use `plt.show()`. This command tells `matplotlib` to return our plot. **This argument is vital**. When I was first learning Python, I did not understand the need for this function. As a result, no plot would display when I ran my code. If no plot displays, you likely forget to add `plt.show()` in your code\n",
    "\n",
    "Let's now plot a line instead. We will create a lists of x and y points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = [0, 1, 2, 3, 4]\n",
    "y = [0, 1, 4, 9, 16]\n",
    "\n",
    "plt.plot(x, y)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Colors, Styles, and Opacity. Oh my!\n",
    "While the above blue is fine, often you want to control the colors directly. You can do this by passing the optional argument `c` and specify the color you want the line to be. `matplotlib` has a variety of keywords for different colors. I never remember them, so I recommend looking at https://matplotlib.org/examples/color/named_colors.html (I refer to this regularly when creating plots)\n",
    "\n",
    "To change how the line displays, we can specify the optional argument `linestyle`. The different options available for `linestyle` are available here: https://matplotlib.org/gallery/lines_bars_and_markers/line_styles_reference.html\n",
    "\n",
    "To change how points are displayed, we can specify the optional argument `marker`. The available options are detailed here: https://matplotlib.org/api/markers_api.html\n",
    "\n",
    "Lastly, we can change the opacity (transparency) of the lines. To do this, we can use the argument `alpha`. `alpha` is bounded between 0 and 1, where 0 is completely transparent and 1 is completely opaque\n",
    "\n",
    "Now that we have these tools, let's redo our previous plot. This time we will plot a red dashed-line, with square points, and a slight transparency"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(x, y, linestyle='--', marker='s', c='red')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Absolute Control Over Axes\n",
    "Now that we have our plot, we might want to add some labels and control which regions of the plot are displayed. We do this through using additional `matplotlib` arguments. Below is an example that I will break down"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(x, y, linestyle='--', marker='s', c='red')\n",
    "plt.xlim([0.5, 2.5])  # Controls the x region displayed\n",
    "plt.ylim([0.5, 6])  # Controls the y region displayed\n",
    "plt.xlabel('x')  # Controls the x-axis label\n",
    "plt.ylabel('x-squared')  # Controls the y-axis label\n",
    "plt.xticks([1, 2])  # Controls the x-ticks displayed\n",
    "plt.yticks([1, 4], ['one', 'four'])  # Controls the y-ticks displayed\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As shown, `xlim` and `ylim` control the region space displayed by `matplotlib`. The default limits automatically make sure all points are displayed. `xlabel` and `ylabel` control the axes labels. `xticks` and `yticks` display the ticks. To replace specific labels with other numbers, you can provide an additional list of labels to be used for the corresponding points. This is shown in `yticks` in the above example.\n",
    "\n",
    "### Saving plots\n",
    "To save your plot, you should use `savefig()` function. It allows you to control and file type and the DPI (image resolution). As an example, let's save our previous plot to our current directory. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.plot(x, y, linestyle='--', marker='s', c='red')\n",
    "plt.xlim([0.5, 2.5])\n",
    "plt.ylim([0.5, 6])\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('x-squared')\n",
    "plt.xticks([1, 2])\n",
    "plt.yticks([1, 4], ['one', 'four'])\n",
    "# plt.tight_layout makes sure nothing is cut-off when saving\n",
    "plt.tight_layout()\n",
    "# Saving the plot AFTER all our formatting and BEFORE show()/close()\n",
    "plt.savefig('example_plot.png', format='png', dpi=300)\n",
    "plt.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note where the `savefig` function is used. It should be included after all the necessary plotting steps but before `plt.show()`. I also used another option we have not seen before. That is `plt.close()`. Like `plt.show()` that tells matplotlib we are done with the plot. However, `plt.close()` instead ends the plot without displaying it. This is useful if you don't want to look at each plot you generate and only want to save them to an external file. \n",
    "\n",
    "### Smoothing Lines\n",
    "Our plot is meant to display $y = x^2$ but it is not that smooth. At each point, our plot bends unnaturally from the function we are plotting. There are two options we can use to smooth our line. Each option is dependent on the scenario we are in\n",
    "\n",
    "#### Known Function\n",
    "If we know the function, we can easily use `numpy` to generate an array of numbers then apply that function to the array. This would give `matplotlib` enough data points to make the plot appear to be smooth. `np.linspace` will generate an evenly-spaced array of numbers from $start$ to $stop$. We will have 100 points created between 0 to 4. We then calculate y based on our function, then plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "x_s = np.linspace(0, 4, num=100)\n",
    "y_s = x_s**2\n",
    "\n",
    "plt.plot(x, y, linestyle='', marker='s', c='red')\n",
    "plt.plot(x_s, y_s, linestyle='--', c='red')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note, that I stacked `plot` statements. You can keep stacking different displays into a single plot. This is how you would display multiple lines. Now our curve looks nice and smooth. Hooray!\n",
    "\n",
    "#### Unknown function\n",
    "When we don't know the true function, we need a different approach. We can use `scipy` to create an arbitrary spline to fit our data. This will result in a nice smooth plot. Let's demonstrate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\zivic\\appdata\\local\\programs\\python\\python36\\lib\\site-packages\\ipykernel_launcher.py:6: DeprecationWarning: `spline` is deprecated!\n",
      "spline is deprecated in scipy 0.19.0, use Bspline class instead.\n",
      "  \n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy.interpolate import spline\n",
    "\n",
    "# Creating corresponding x values\n",
    "x_t = np.linspace(0, 4, num=100)\n",
    "# Spline values for np.linspace following observed points\n",
    "y_t = spline(x, y, x_s)\n",
    "\n",
    "plt.plot(x, y, linestyle='', marker='s', c='red')\n",
    "plt.plot(x_t, y_t, linestyle='--', c='red')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Hooray! Our curve is smooth again and we didn't even need to know the true function to do it. `scipy.interpolate.spline` is deprecated (as indicated in the warning), so you should use Bspline instead (as the warning recommends)\n",
    "\n",
    "This concludes the absolute basics of plotting. You are now ready to create your own plots. \n",
    "\n",
    "## Example Plots\n",
    "Let's go through some examples with an actual data set (rather than the arbitrary function I chose). I will assume you have went through the data management tutorial before this. We will use the SAS data set included in this directory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 547 entries, 0 to 546\n",
      "Data columns (total 8 columns):\n",
      "id      547 non-null float64\n",
      "male    547 non-null float64\n",
      "age0    547 non-null float64\n",
      "cd40    547 non-null float64\n",
      "dvl0    547 non-null float64\n",
      "art     547 non-null float64\n",
      "dead    517 non-null float64\n",
      "t       547 non-null float64\n",
      "dtypes: float64(8)\n",
      "memory usage: 34.3 KB\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "df = pd.read_sas('sample_sas.sas7bdat')\n",
    "df.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's start with a basic histogram of CD4 T-cell counts (`cd40`). To accomplish this, we will use `plt.hist()`. The first argument in `hist` is the array of values we want to generate the histogram with. We will also specify the `bins` option, which allows us to control the number of bins"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist(df['cd40'], bins=50)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Awesome! Let's stratify by `art` to see who was treated at baseline versus who was not. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Subsetting out the data I want to plot\n",
    "yes_art = df.loc[df['art']==1, 'cd40'].copy()\n",
    "no_art = df.loc[df['art']==0, 'cd40'].copy()\n",
    "\n",
    "# Creating histogram\n",
    "plt.hist(no_art, color='red', bins=20, alpha=1, label='No ART', density=True)\n",
    "plt.hist(yes_art, color='blue', bins=20, alpha=0.5, label='ART', density=True)\n",
    "plt.legend()\n",
    "plt.title('CD4 T-cell count by baseline ART')\n",
    "plt.xlabel('CD4 T-cell count')\n",
    "plt.ylabel('Density')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I added a few more arguments and functions. First, `hist(..., density=True)` plots the density at each point rather than the count. `hist(..., label)` gives a label to each part of the plot. These labels are used by `plt.legend()` to create our legend. Finally, I added a title with `plt.title`. \n",
    "\n",
    "While I like this histogram, we can do better. Specifically, we can use kernel-smoothing to get a nice smooth plot of CD4 T-cell counts by ART treatment. To do this, we will use `scipy` to access some kernel smoothers. Below is an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy.stats.kde import gaussian_kde\n",
    "\n",
    "# Kernel Density Estimating\n",
    "yes_art_d = gaussian_kde(yes_art)\n",
    "no_art_d = gaussian_kde(no_art)\n",
    "\n",
    "# Values to plot between\n",
    "xvals = np.linspace(np.min(df['cd40']), np.max(df['cd40']), 100)\n",
    "\n",
    "# Plotting Smoothed \n",
    "plt.plot(xvals, no_art_d(xvals), color='red', alpha=1, label='No ART')\n",
    "plt.plot(xvals, yes_art_d(xvals), color='blue', alpha=1, label='ART')\n",
    "plt.legend()\n",
    "plt.title('CD4 T-cell count by baseline ART')\n",
    "plt.xlabel('CD4 T-cell count')\n",
    "plt.ylabel('Density')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Great! I like this format a little better (even though we do lose information). However, we can do even better. Let's shade in the areas under the curves. We can do that by using `plt.fill_between()`. Not that I do the fill between part before the lines! This is because matplotlib follows the order of operations when overlaying additional plot items"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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
gitextract_95lr8jsa/

├── .gitignore
├── 1_Python-Basics/
│   └── intro_to_python.ipynb
├── 2_Data-Basics/
│   ├── 1_data_management.ipynb
│   ├── 2_intro_to_plots.ipynb
│   ├── 3_simulating_data.ipynb
│   ├── sample_csv.csv
│   └── sample_sas.sas7bdat
├── 3_Epidemiology_Analysis/
│   ├── a_basics/
│   │   ├── 1_basic_measures.ipynb
│   │   └── 2_functional_forms.ipynb
│   ├── b_missing_data/
│   │   ├── 1_IPMW_one_variable.ipynb
│   │   └── 4_IPCW.ipynb
│   ├── c_causal_inference/
│   │   ├── 1_time-fixed-treatments/
│   │   │   ├── 01_g-formula.ipynb
│   │   │   ├── 02_gformula_stochastic.ipynb
│   │   │   ├── 03_IPTW_intro.ipynb
│   │   │   ├── 04_IPTW_SMR.ipynb
│   │   │   ├── 05_AIPTW_intro.ipynb
│   │   │   ├── 06_AIPTW_continuous.ipynb
│   │   │   ├── 07_TMLE_intro.ipynb
│   │   │   ├── 08_TMLE_continuous.ipynb
│   │   │   ├── 09_TMLE_missing_data.ipynb
│   │   │   └── 10_TMLE_stochastic.ipynb
│   │   ├── 2-time-varying-treatments/
│   │   │   ├── 1_MonteCarlo_G-formula.ipynb
│   │   │   ├── 2_MonteCarlo_G-formula_keil2014.ipynb
│   │   │   └── 4_IterativeConditional_GFormula.ipynb
│   │   ├── 3-generalizability-transportability/
│   │   │   ├── 1-generalizability.ipynb
│   │   │   └── README.md
│   │   └── README.md
│   └── d_sensitivity_analyses/
│       └── 1_MonteCarlo_RR.ipynb
├── 4_Hernan-Robins/
│   ├── Chapter-12.ipynb
│   ├── Chapter-13.ipynb
│   ├── Chapter-14.ipynb
│   ├── Data/
│   │   ├── NHEFS.xls
│   │   └── nhefs.csv
│   └── README.md
├── 5_Random_Demonstrations/
│   ├── Bayesian_Priors.ipynb
│   ├── Funk_2011_replication/
│   │   ├── aipw_example_python.ipynb
│   │   ├── aipw_example_r.R
│   │   ├── aipw_example_sas.sas
│   │   ├── dgm.py
│   │   ├── dr_data.csv
│   │   ├── funk_sim_rep.py
│   │   └── sim_results.md
│   ├── Model-Misspecification.ipynb
│   ├── Monty_Hall_Example.ipynb
│   ├── Super_Learner_Demonstration.ipynb
│   ├── Survey-Weights.ipynb
│   ├── Survivor_Bias.ipynb
│   └── stg_examples.py
└── README.md
Condensed preview — 47 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,489K chars).
[
  {
    "path": ".gitignore",
    "chars": 25,
    "preview": ".ipynb_checkpoints\n.idea\n"
  },
  {
    "path": "1_Python-Basics/intro_to_python.ipynb",
    "chars": 22392,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Introduction to Python\\n\",\n    \"H..."
  },
  {
    "path": "2_Data-Basics/1_data_management.ipynb",
    "chars": 38145,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Introduction to Data Management\\n..."
  },
  {
    "path": "2_Data-Basics/2_intro_to_plots.ipynb",
    "chars": 206463,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Graphics in Python\\n\",\n    \"In th..."
  },
  {
    "path": "2_Data-Basics/3_simulating_data.ipynb",
    "chars": 15613,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Simulating Data with NumPy\\n\",..."
  },
  {
    "path": "2_Data-Basics/sample_csv.csv",
    "chars": 2771788,
    "preview": "A,L,B_true,C_true,M2,M3,B,C,id\n0,1.167,1,1,1,1,,,0\n0,-1.79,1,1,0,1,1.0,,1\n0,-0.605,1,1,0,1,1.0,,2\n1,-1.172,0,0,1,1,,,3\n0..."
  },
  {
    "path": "3_Epidemiology_Analysis/a_basics/1_basic_measures.ipynb",
    "chars": 17717,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Measures\\n\",\n    \"This tutorial d..."
  },
  {
    "path": "3_Epidemiology_Analysis/a_basics/2_functional_forms.ipynb",
    "chars": 240572,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Functional Form Assessment\\n\",..."
  },
  {
    "path": "3_Epidemiology_Analysis/b_missing_data/1_IPMW_one_variable.ipynb",
    "chars": 13279,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Inverse Probability of Missing We..."
  },
  {
    "path": "3_Epidemiology_Analysis/b_missing_data/4_IPCW.ipynb",
    "chars": 63489,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Inverse Probability of Censoring..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/01_g-formula.ipynb",
    "chars": 41094,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Parametric g-formula\\n\",\n    \"The..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/02_gformula_stochastic.ipynb",
    "chars": 10618,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Parametric g-formula: stochastic..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/03_IPTW_intro.ipynb",
    "chars": 76832,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Inverse Probability of Treatment..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/04_IPTW_SMR.ipynb",
    "chars": 18977,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Inverse Probability of Treatment..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/05_AIPTW_intro.ipynb",
    "chars": 63946,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Augmented Inverse Probability of..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/06_AIPTW_continuous.ipynb",
    "chars": 13059,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Augmented Inverse Probability of..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/07_TMLE_intro.ipynb",
    "chars": 67701,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Targeted Maximum Likelihood Estim..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/08_TMLE_continuous.ipynb",
    "chars": 9492,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Targeted Maximum Likelihood Estim..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/09_TMLE_missing_data.ipynb",
    "chars": 8202,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Targeted Maximum Likelihood Estim..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/1_time-fixed-treatments/10_TMLE_stochastic.ipynb",
    "chars": 65383,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Targeted Maximum Likelihood Estim..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/2-time-varying-treatments/1_MonteCarlo_G-formula.ipynb",
    "chars": 93390,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# G-formula: Monte Carlo Estimator\\..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/2-time-varying-treatments/2_MonteCarlo_G-formula_keil2014.ipynb",
    "chars": 81723,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# G-formula: Monte Carlo Estimator\\..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/2-time-varying-treatments/4_IterativeConditional_GFormula.ipynb",
    "chars": 20401,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Iterative-Conditional G-Formula\\n..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/3-generalizability-transportability/1-generalizability.ipynb",
    "chars": 26831,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Generalizability\\n\",\n    \"First,..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/3-generalizability-transportability/README.md",
    "chars": 3034,
    "preview": "This section details generalizability and transportability\n\n# Generalizability\nGeneralizability is the concept that our..."
  },
  {
    "path": "3_Epidemiology_Analysis/c_causal_inference/README.md",
    "chars": 4219,
    "preview": "Throughout the following tutorials in this branch, we will make the following identifiability assumptions. \nWe additiona..."
  },
  {
    "path": "3_Epidemiology_Analysis/d_sensitivity_analyses/1_MonteCarlo_RR.ipynb",
    "chars": 50954,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Quantitative Bias Analysis: Monte..."
  },
  {
    "path": "4_Hernan-Robins/Chapter-12.ipynb",
    "chars": 207464,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Chapter 12: IPW and Marginal Stru..."
  },
  {
    "path": "4_Hernan-Robins/Chapter-13.ipynb",
    "chars": 7842,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Chapter 13: Standardization and t..."
  },
  {
    "path": "4_Hernan-Robins/Chapter-14.ipynb",
    "chars": 15073,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Chapter 14: G-estimation of Struc..."
  },
  {
    "path": "4_Hernan-Robins/Data/nhefs.csv",
    "chars": 364535,
    "preview": "seqn,qsmk,death,yrdth,modth,dadth,sbp,dbp,sex,age,race,income,marital,school,education,ht,wt71,wt82,wt82_71,birthplace,s..."
  },
  {
    "path": "4_Hernan-Robins/README.md",
    "chars": 1082,
    "preview": "# Replications of \"Causal Inference\"\n\nDirectory containing replications of Part II of\n“Hernán MA, Robins JM (2019). Caus..."
  },
  {
    "path": "5_Random_Demonstrations/Bayesian_Priors.ipynb",
    "chars": 92003,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Bayesian Priors\\n\",\n    \"The purp..."
  },
  {
    "path": "5_Random_Demonstrations/Funk_2011_replication/aipw_example_python.ipynb",
    "chars": 14943,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Demonstration of AIPW with a sing..."
  },
  {
    "path": "5_Random_Demonstrations/Funk_2011_replication/aipw_example_r.R",
    "chars": 1362,
    "preview": "####################################################################\n# Demonstration of AIPW with a single sample\n#   Da..."
  },
  {
    "path": "5_Random_Demonstrations/Funk_2011_replication/aipw_example_sas.sas",
    "chars": 1768,
    "preview": "**********************************************************************\n* Demonstration of AIPW with a single sample\n*\tDa..."
  },
  {
    "path": "5_Random_Demonstrations/Funk_2011_replication/dgm.py",
    "chars": 524,
    "preview": "import numpy as np\nimport pandas as pd\n\nn = 5000\n\n# Generating covariates\nz1 = np.random.normal(size=n)\nz2 = np.random.n..."
  },
  {
    "path": "5_Random_Demonstrations/Funk_2011_replication/dr_data.csv",
    "chars": 312613,
    "preview": "Z1,Z2,Z3,X,Y\n1.0023227802368215,-0.5221332643624579,0,0,1.8521144474420739\n0.14684264312162562,1.028294671828141,0,1,-1...."
  },
  {
    "path": "5_Random_Demonstrations/Funk_2011_replication/funk_sim_rep.py",
    "chars": 4856,
    "preview": "import numpy as np\nimport pandas as pd\nimport statsmodels.api as sm\nimport statsmodels.formula.api as smf\nimport matplot..."
  },
  {
    "path": "5_Random_Demonstrations/Funk_2011_replication/sim_results.md",
    "chars": 1198,
    "preview": "All scenarios were 2500 replications of n=2000\n\nSCENARIO 1 (both models correct)\n=================================\n\nBias..."
  },
  {
    "path": "5_Random_Demonstrations/Model-Misspecification.ipynb",
    "chars": 60279,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Demonstration of Model Misspecifi..."
  },
  {
    "path": "5_Random_Demonstrations/Monty_Hall_Example.ipynb",
    "chars": 5774,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Monty Hall Problem\\n\",\n    \"\\n\",..."
  },
  {
    "path": "5_Random_Demonstrations/Super_Learner_Demonstration.ipynb",
    "chars": 97612,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Super Learner\\n\",\n    \"Demonstrat..."
  },
  {
    "path": "5_Random_Demonstrations/Survey-Weights.ipynb",
    "chars": 35679,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Demonstration of the Importance o..."
  },
  {
    "path": "5_Random_Demonstrations/Survivor_Bias.ipynb",
    "chars": 33369,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Survivor Bias\\n\",\n    \"Below is a..."
  },
  {
    "path": "5_Random_Demonstrations/stg_examples.py",
    "chars": 13556,
    "preview": "import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom matplotlib import animation\nimport statsmode..."
  },
  {
    "path": "README.md",
    "chars": 5180,
    "preview": "# Python-for-Epidemiologists\n[![Join the chat at https://gitter.im/zEpid/community](https://badges.gitter.im/zEpid/commu..."
  }
]

About this extraction

This page contains the full source code of the pzivich/Python-for-Epidemiologists GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 49 files (5.1 MB), approximately 1.3M tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!