phplyr
Examples

Porting an R analysis

A dplyr and tidyr analysis of 250 students, translated line by line and run live, with the pass mark and study-time bands as inputs.
Uses phibble phplyr phit

Inputs

Running

This analysis of 250 students in 12 schools was written in R with dplyr and tidyr. phplyr keeps the function and argument names, so the translation is mostly syntax: bare column names become strings or col(), = becomes :, and .default becomes default. The inputs change the pass mark and the study-time bands; the code below shows the defaults.

The R original:

clean <- schools |>
  filter(!is.na(score), study_hours > 0) |>
  mutate(
    hours_band = case_when(study_hours < 4 ~ "low", study_hours < 8 ~ "mid", .default = "high"),
    gain = score - prior_score,
    passed = as.integer(score >= 75)
  )

clean |>
  group_by(school) |>
  summarize(n = n(), mean_gain = mean(gain), pass_rate = mean(passed)) |>
  arrange(desc(mean_gain))
$clean = $schools |>
    filter(col('score')->isNa()->not(), col('study_hours')->gt(0)) |>
    mutate(
        hours_band: case_when([col('study_hours')->lt(4), 'low'], [col('study_hours')->lt(8), 'mid'], default: 'high'),
        gain: col('score')->sub(col('prior_score')),
        passed: if_else(col('score')->ge(75), 1, 0),
    );

$gains = $clean |>
    group_by('school') |>
    summarize(n: n(), mean_gain: mean('gain'), pass_rate: mean('passed')) |>
    arrange(desc('mean_gain'));
$clean = phplyr($schools)
    ->filter(col('score')->isNa()->not(), col('study_hours')->gt(0))
    ->mutate(
        hours_band: case_when([col('study_hours')->lt(4), 'low'], [col('study_hours')->lt(8), 'mid'], default: 'high'),
        gain: col('score')->sub(col('prior_score')),
        passed: if_else(col('score')->ge(75), 1, 0),
    )
    ->get();

$gains = phplyr($clean)
    ->groupBy('school')
    ->summarize(n: n(), mean_gain: mean('gain'), pass_rate: mean('passed'))
    ->arrange(desc('mean_gain'))
    ->get();
Students
250
Pass rate
39.6%
Mean gain
12.21

Schools by mean gain

school n mean_gain pass_rate
school-07 19 24.287 0.842
school-10 25 14.138 0.320
school-02 24 13.641 0.458
school-09 16 13.367 0.500
school-03 15 12.912 0.333
school-11 23 12.286 0.348
school-06 27 12.231 0.481
school-05 20 11.338 0.550
school-01 18 9.904 0.389
school-12 20 8.681 0.150
school-08 21 8.667 0.095
school-04 22 5.893 0.318

Mean gain and pass rate by study-time band

Reshaping works the same way. pivot_longer() gives one row per student and test, and pivot_wider() spreads the band counts into columns.

Prior and final scores

test mean sd
final 71.989 10.314
prior 59.777 12.441

Students per school and band

school high low mid
school-01 7 4 7
school-02 8 8 8
school-03 5 3 7
school-04 13 1 8
school-05 9 6 5
school-06 15 4 8
school-07 9 4 6
school-08 5 6 10
school-09 5 3 8
school-10 7 8 10
school-11 8 9 6
school-12 4 9 7

With the phit extension loaded, lm() and glm() fit models to the table, as R's functions do.

$fit = $clean |> lm('score ~ study_hours + prior_score');
$logit = $clean |> glm('passed ~ study_hours + prior_score', family: 'binomial');
$fit = phplyr($clean)->lm('score ~ study_hours + prior_score');
$logit = phplyr($clean)->glm('passed ~ study_hours + prior_score', family: 'binomial');

Linear model of the final score

Term Estimate Std. error t p 95% CI
(Intercept) 45.3014 2.3222 19.51 < 0.0001 [40.727, 49.875]
study_hours 1.5691 0.2054 7.64 < 0.0001 [1.165, 1.974]
prior_score 0.2730 0.0530 5.15 < 0.0001 [0.168, 0.377]

n = 250, R² = 0.5972, σ = 6.5719, log-likelihood = -823.93

Logistic model of passing (score ≥ 75)

Term Estimate Std. error z p 95% CI
(Intercept) -6.9865 1.2400 -5.63 < 0.0001 [-9.417, -4.556]
study_hours 0.5688 0.0991 5.74 < 0.0001 [0.375, 0.763]
prior_score 0.0395 0.0235 1.68 0.0922 [-0.006, 0.086]

n = 250, log-likelihood = -98.13, AIC = 202.3, deviance = 196.26

Script: site/vignettes/port-r-script.php in phpstats/phplyr@d319dc5.