phplyr

Reference

Models

lm(), glm(), lmer(), and glmer() pass the table to the phit extension’s Phit\fit_lm(), Phit\fit_glm(), Phit\fit_lmer(), and Phit\fit_glmer(). phplyr adds no model code of its own. phit reads factor levels from the table, builds the model matrix from an R formula, and fits the model.

$table |> lm('y ~ x + group');
$table |> glm('passed ~ hours', family: 'binomial');
$table |> lmer('score ~ hours + (1 | school)');
$table |> glmer('passed ~ hours + (1 | school)', family: 'binomial');
phplyr($table)->lm('y ~ x + group');
phplyr($table)->glm('passed ~ hours', family: 'binomial');
phplyr($table)->lmer('score ~ hours + (1 | school)');
phplyr($table)->glmer('passed ~ hours + (1 | school)', family: 'binomial');
Function Model Options
lm($formula) Linear regression
glm($formula, family:) Generalized linear model family: 'gaussian' (the default), 'binomial', or 'poisson', and link:
lmer($formula) Linear mixed model with lme4’s random-effect terms, such as (1 \| school) REML by default; reml: false fits by maximum likelihood
glmer($formula, family:) Generalized linear mixed model family: 'binomial' by default

Other named arguments go to phit’s function unchanged. phit’s documentation lists them and the formula syntax it accepts.

Results

Each function returns phit’s result array in place of a table, so it ends a method chain. columns holds R’s coefficient names, in R’s order, and coefficients, std_errors, p_values, and conf_int follow the same order. The array also has the fitted values, residuals, fit statistics such as r_squared and sigma, and n_observations and n_dropped, which count the rows used and the rows dropped for missing values.

$fit = DataFrame::fromCsv('schools.csv') |>
    filter(fn ($r) => $r->prior_score > 50) |>
    lm('score ~ study_hours + prior_score');

foreach (['(Intercept)', 'study_hours', 'prior_score'] as $i => $term) {
    printf("%-12s %8.4f  (se %.4f)\n", $term, $fit['coefficients'][$i], $fit['std_errors'][$i]);
}
printf("R² = %.4f, n = %d\n", $fit['r_squared'], $fit['n_observations']);

$logit = DataFrame::fromCsv('learning.csv') |> glm('passed ~ study_hours + practice_score', family: 'binomial');
echo 'logit coefficients: ', implode(', ', array_map(fn ($b) => round($b, 4), $logit['coefficients'])), "\n";
$fit = phplyr(DataFrame::fromCsv('schools.csv'))
    ->filter(fn ($r) => $r->prior_score > 50)
    ->lm('score ~ study_hours + prior_score');

foreach (['(Intercept)', 'study_hours', 'prior_score'] as $i => $term) {
    printf("%-12s %8.4f  (se %.4f)\n", $term, $fit['coefficients'][$i], $fit['std_errors'][$i]);
}
printf("R² = %.4f, n = %d\n", $fit['r_squared'], $fit['n_observations']);

$logit = phplyr(DataFrame::fromCsv('learning.csv'))->glm('passed ~ study_hours + practice_score', family: 'binomial');
echo 'logit coefficients: ', implode(', ', array_map(fn ($b) => round($b, 4), $logit['coefficients'])), "\n";
(Intercept)   43.4427  (se 3.8669)
study_hours    1.5135  (se 0.2256)
prior_score    0.3074  (se 0.0736)
R² = 0.4914, n = 193
logit coefficients: -3.171, 0.0637, 0.0342

Without the extension

Without phit, the four functions throw a RuntimeException that names the missing phit function.

phit-polyfill defines the same functions in PHP for systems without the extension, and phplyr calls them the same way. CI runs phplyr’s test suite twice for the models: once with the phit extension and once with phit-polyfill and no extension. Both runs compare lm() and glm() coefficients with R’s and lmer() fixed effects with lme4’s.

From phpstats/phplyr@d319dc5.