Two-way ANOVA for repeated measures using Python

Previously I have shown how to analyze data collected using within-subjects designs using rpy2 (i.e., R from within Python) and Pyvttbl. In this post I will extend it into a factorial ANOVA using Python (i.e., Pyvttbl). In fact, we are going to carry out a Two-way ANOVA but the same method will enable you to analyze any factorial design. I start with importing the Python libraries that  are going to be use.

Numpy is going to be used to simulate data. I create a data set in which we have one factor of two levels (P) and a second factor of 3 levels (Q). As in many of my examples the dependent variable is going to be response time (rt) and we create a list of lists for the different population means we are going to assume (i.e., the variable ‘values’). I was a bit lazy when coming up with the data so I named the independent variables ‘iv1’ and ‘iv2’. However, you could think of iv1 as two different memory tasks; verbal and spatial memory. Iv2 could be different levels of distractions (no distraction, synthetic sounds, and speech, for instance).

Simulate data

I start with a boxplot using the method boxplot from Pyvttbl. As far as I can see there is not much room for changing the plot around. We get this plot and it is really not that beautiful.

A Boxplot before we do our Python two-way ANOVA
Boxplot Pyvttbl

Two-way ANOVA for within-subjects design in Python

To run the Two-Way ANOVA is simple; the first argument is the dependent variable, the second the subject identifier, and than the within-subject factors. In two previous posts I showed how to carry out one-way and two-way ANOVA for independent measures. One could, of course combine these techniques, to do a split-plot/mixed ANOVA by adding an argument ‘bfactors’ for the between-subject factor(s).

The output one get from this is an ANOVA table. In this table all metrics needed plus some more can be found; F-statistic, p-value, mean square errors, confidence intervals, effect size (i.e., eta-squared) for all factors and the interaction. Also, some corrected degree of freedom and mean square error can be found (e.g., Grenhouse-Geisser corrected). The output is in the end of the post. It is a bit hard to read.  If you know any other way to do a repeated measures ANOVA using Python please let me know. Also, if you happen to know that you can create nicer plots with Pyvttbl I would also like to know how! Please leave a comment.

Update (2017-07-03): If your installed version of Numpy is greater than 1.11.x, you will run into a Float and NoneType error. One quick solution for this is to downgrade Numpy to 1.11.x. I created a post, Step-by-step guide for solving the Pyvttbl Float and NoneType error, in which I show how to install Numpy 1.11.x in an virtual environment. This way, you can run your ANOVAs, without having to uninstall Numpy.

Output ANOVA table

6 thoughts on “Two-way ANOVA for repeated measures using Python

  1. Hi there. Thanks for your excellent blog. I’m trying to run a two-way repeated mesures ANOVA using pyvttbl as you explain. I use python 2.7 and installed pyvttbl via pip. I was able to import pyvttbl and create the dataframe just fine. However, when I run the test, I get this error: TypeError: unsupported operand type(s) for +: ‘float’ and ‘NoneType’. Can you help? Thanks in advance!

    1. Hey Veronica,

      Have you solved the problem? When I wrote this blog, this did not happen. However, I tried to run the script again and get the same problem. I am not sure what is going on here but I will try to find out given that you did not solve it.

      Please let me know if and how you solved the problem.

      Erik

  2. Hi Erik,
    I met the same problem when I ran my analysis. In my study, the design is a 2x3x3 repeated measure ANOVA. And my code is straightforward, import pyvttbl as pt
    df = pt.DataFrame()
    df.read_tbl(‘Z_score_filtered.csv’)

    aov = df.anova(‘Z_score’, sub=’ID’, wfactors=[‘Task_types’, ‘conditions’, ‘Question’])
    print(aov)
    But it returned the error “unsupported operand type(s) for +: ‘float’ and ‘NoneType'”. I have checked my data file and found Z_score was stored as numpy.float64. Is it the reason I have this error message? Should I change my data from numpy.float64 to long or other data type?
    Thanks for your help!

    1. Hey Shengjie,

      Right now I don’t have a solution for this problem other than the one Damien gave here in the comments. It seems like you have to have Python 1.11.0 (maybe other versions work to but it worked for Damien). Hope it helps. I will update my post(s) with this solution. I don’t think Pyvttbl have been updated for 4 years, or so. Maybe someone should build a new package/update Pyvttbl. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *