Fit a mixed model to a Polars table and chart it
On this page
Read a CSV file with Polars, fit reaction time with a random intercept for each subject, and chart each subject’s fitted line with phiz.
The example needs the phpolars extension (phpolars installation) and phiz (composer require phpstats/phiz). phit can be the extension or the plain-PHP polyfill (Extension or polyfill). Runnable script
The data are sleepstudy: average reaction time in milliseconds per day for 18 subjects in a sleep-deprivation study, days 0 to 9. Polars reads the file by URL.
Code
use Phiz\Plot;use function Phit\{fit_mixed_gaussian, summary};use function Phpolars\scan_csv;$data = scan_csv( 'https://raw.githubusercontent.com/phpstats/datasets/main/csv/sleepstudy.csv',) ->select(['Reaction', 'Days', 'Subject']) ->collect() ->toColumns();// A random intercept per subject, fitted by REML.$fit = fit_mixed_gaussian( 'Reaction ~ Days + (1 | Subject)', $data,);$data['fitted'] = $fit['fitted'];echo summary($fit);// Each subject's days as points, and one fitted line per subject.$chart = Plot::of($data) ->aes(x: 'Days', y: 'Reaction') ->point(alpha: 0.4) ->line( aes: ['y' => 'fitted', 'group' => 'Subject'], alpha: 0.6, ) ->labs(x: 'Days of sleep deprivation', y: 'Reaction time (ms)') ->theme(baseSize: 15) ->size('container', 380);file_put_contents( 'sleepstudy.html', $chart->html('Reaction time by subject'),);Output
Linear mixed model fit by REML
Formula: Reaction ~ Days + (1 | Subject)
REML criterion at convergence: 1786.5
Random effects:
Groups Name Variance Std.Dev.
Subject (Intercept) 1378.2 37.12
Residual 960.5 30.99
Number of obs: 180, groups: Subject, 18
Fixed effects:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 251.4051 9.7467 25.79 <2e-16
Days 10.4673 0.8042 13.02 <2e-16
Interpretation
toColumns()converts the Polars result to PHP arrays once for use by phit and phiz.- The
Dayscoefficient is the average change in reaction time per additional day of sleep deprivation. fittedholds conditional fitted values, which include each subject’s predicted intercept.fixed_fittedleaves them out.- The model gives every subject the same slope, so the fitted lines are parallel. The points show that the slopes differ between subjects;
(Days | Subject)fits a random slope as well.
See also: Fit a mixed model for reading the variance components and subject effects · Mixed models for the supported structures · phpolars’ Getting started · phiz’s Get started