title: Creating a summary statistics table in python
body: <p>I am trying to recreate the 'SummarySE()' function from R in python but I am having trouble getting it to work. The function creates a summary stats table from a repeated measures dataframe.
  However I am unable to get it working, I keep getting errors due to the column names within my dataframe (which are strings).</p>
  <p>Table used:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>id</th>
  <th>Position.Name</th>
  <th>Period</th>
  <th>Maximum.Velocity</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>Special team</td>
  <td>16.5</td>
  </tr>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>Special team</td>
  <td>15.2</td>
  </tr>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>Special team</td>
  <td>16.5</td>
  </tr>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>Special team</td>
  <td>15.2</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>Special team</td>
  <td>14.5</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>Special team</td>
  <td>10.6</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>Special team</td>
  <td>17.5</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>Special team</td>
  <td>13.5</td>
  </tr>
  <tr>
  <td>4</td>
  <td>OL</td>
  <td>Special team</td>
  <td>10.2</td>
  </tr>
  <tr>
  <td>4</td>
  <td>OL</td>
  <td>Special team</td>
  <td>11.3</td>
  </tr>
  <tr>
  <td>4</td>
  <td>OL</td>
  <td>Special team</td>
  <td>16.2</td>
  </tr>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>team</td>
  <td>13.5</td>
  </tr>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>team</td>
  <td>12.2</td>
  </tr>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>team</td>
  <td>15.5</td>
  </tr>
  <tr>
  <td>2</td>
  <td>WR</td>
  <td>team</td>
  <td>16.2</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>team</td>
  <td>13.5</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>team</td>
  <td>12.5</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>team</td>
  <td>11.5</td>
  </tr>
  <tr>
  <td>3</td>
  <td>DB</td>
  <td>team</td>
  <td>16.5</td>
  </tr>
  <tr>
  <td>4</td>
  <td>OL</td>
  <td>team</td>
  <td>9.2</td>
  </tr>
  <tr>
  <td>4</td>
  <td>OL</td>
  <td>team</td>
  <td>8.2</td>
  </tr>
  <tr>
  <td>4</td>
  <td>OL</td>
  <td>team</td>
  <td>11.2</td>
  </tr>
  </tbody>
  </table>
  </div>
  <pre><code>df = pd.DataFrame(columns=[&quot;id&quot;, &quot;Position.Name&quot;, &quot;Period&quot;, &quot;Maximum.Velocity&quot;], 
                    data = [[2, &quot;WR&quot;, &quot;Special team&quot;, 16.5],[2, &quot;WR&quot;, &quot;Special team&quot;, 15.2], [2, &quot;WR&quot;, &quot;Special team&quot;, 16.5], [2,&quot;WR&quot;, &quot;Special team&quot;, 15.2],  [3, &quot;DB&quot;, &quot;Special team&quot; ,14.5],[3, &quot;DB&quot;, &quot;Special team&quot;, 10.6], [3, &quot;DB&quot;, &quot;Special team&quot;, 17.5],[3, &quot;DB&quot;, &quot;Special team&quot;, 13.5], [4, &quot;OL&quot;, &quot;Special team&quot;, 10.2], [4, &quot;OL&quot;, &quot;Special team&quot;, 11.3], [4, &quot;OL&quot;, &quot;Special team&quot;, 16.2], [2, &quot;WR&quot;, &quot;team&quot;, 13.5], [2, &quot;WR&quot;, &quot;team&quot;, 12.2], [2, &quot;WR&quot;, &quot;team&quot;, 15.5],[2, &quot;WR&quot;, &quot;team&quot;, 16.2],[3, &quot;DB&quot;, &quot;team&quot;, 13.5], [3, &quot;DB&quot;, &quot;team&quot;, 12.5], [3, &quot;DB&quot;, &quot;team&quot;, 11.5], [3,&quot;DB&quot;,&quot;team&quot;, 16.5], [4, &quot;OL&quot;,&quot;team&quot;, 9.2], [4, &quot;OL&quot;, &quot;team&quot;, 8.2], [4, &quot;OL&quot;, &quot;team&quot;, &quot;11.2&quot;]])
  df[&quot;Maximum.Velocity&quot;] = df[&quot;Maximum.Velocity&quot;].astype(&quot;float&quot;)
  </code></pre>
  <p>Code used:</p>
  <pre><code>import pandas as pd
  import scipy as sp
  from scipy.stats import t
  import numpy as np
  
  #from: http://www.cookbook-r.com/Graphs/Plotting_means_and_error_bars_%28ggplot2%29/
  ## Gives count, mean, standard deviation, standard error of the mean, and confidence interval (default 95%).
  ##   data: a data frame.
  ##   measurevar: the name of a column that contains the variable to be summariezed
  ##   groupvars: a vector containing names of columns that contain grouping variables
  ##   conf_interval: the percent range of the confidence interval (default is 95%)
  def summarySE(data, measurevar, groupvars, conf_interval=0.95):
      def std(s):
          return np.std(s, ddof=1)
      def stde(s):
          return std(s) / np.sqrt(len(s))
  
      def ci(s):
          # Confidence interval multiplier for standard error
          # Calculate t-statistic for confidence interval: 
          # e.g., if conf.interval is .95, use .975 (above/below), and use df=N-1
          ciMult = t.ppf(conf_interval/2.0 + .5, len(s)-1)
          return stde(s)*ciMult
      def ciUp(s):
          return np.mean(s)+ci(s)
      def ciDown(s):
          return np.mean(s)-ci(s)
      
      data = data[groupvars+measurevar].groupby(groupvars).agg([len, np.mean, std, stde, ciUp, ciDown, ci])
  
      data.reset_index(inplace=True)
  
  
      data.columns = groupvars+ ['_'.join(col).strip() for col in data.columns.values[len(groupvars):]]
  
      return data
  
  summary_table = summarySE(data = df, measurevar = ['Maximum.Velocity'], groupvars = ['Position.Name','Period'], conf_interval=0.95)
  
  </code></pre>
  <p>Traceback Error that I get:</p>
  <ul>
  <li>indexer = self.columns.get_loc(key)</li>
  <li>raise KeyError(key) from err</li>
  <li>KeyError: 'Position.NameMaximum.Velocity'</li>
  </ul>
  <p>The desired output is something like this:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>Position.Name</th>
  <th>Period</th>
  <th>length</th>
  <th>Maximum.Velocity</th>
  <th>std</th>
  <th>stde</th>
  <th>ciUp</th>
  <th>ciDown</th>
  <th>ci</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>WR</td>
  <td>Special team</td>
  <td>4</td>
  <td>mean</td>
  <td>std</td>
  <td>stde</td>
  <td>ciUp</td>
  <td>ciDown</td>
  <td>ci</td>
  </tr>
  <tr>
  <td>WR</td>
  <td>team</td>
  <td>4</td>
  <td>mean</td>
  <td>std</td>
  <td>stde</td>
  <td>ciUp</td>
  <td>ciDown</td>
  <td>ci</td>
  </tr>
  <tr>
  <td>DB</td>
  <td>Special team</td>
  <td>4</td>
  <td>mean</td>
  <td>std</td>
  <td>stde</td>
  <td>ciUp</td>
  <td>ciDown</td>
  <td>ci</td>
  </tr>
  <tr>
  <td>DB</td>
  <td>team</td>
  <td>4</td>
  <td>mean</td>
  <td>std</td>
  <td>stde</td>
  <td>ciUp</td>
  <td>ciDown</td>
  <td>ci</td>
  </tr>
  <tr>
  <td>OL</td>
  <td>Special team</td>
  <td>3</td>
  <td>mean</td>
  <td>std</td>
  <td>stde</td>
  <td>ciUp</td>
  <td>ciDown</td>
  <td>ci</td>
  </tr>
  <tr>
  <td>OL</td>
  <td>team</td>
  <td>3</td>
  <td>mean</td>
  <td>std</td>
  <td>stde</td>
  <td>ciUp</td>
  <td>ciDown</td>
  <td>ci</td>
  </tr>
  </tbody>
  </table>
  </div>