The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Learning curves model how efficiency or completion rate evolves over time as a team gains experience. In project management they are used to:
Sigmoidal (S-shaped) functions capture the three phases of learning: slow start, rapid improvement, and plateau. The PRA package provides three model types:
| Model | Formula | Parameters |
|---|---|---|
| Logistic | K / (1 + exp(−r(t − t₀))) | K = ceiling; r = growth rate; t₀ = inflection time |
| Pearl | K / (1 + exp(−r(t − t₀))) | Same as logistic (identical functional form) |
| Gompertz | A · exp(−b · exp(−c · t)) | A = ceiling; c = growth rate; b = initial suppression |
Parameter interpretation (Logistic / Pearl): - K — the maximum achievable value (e.g., 100% completion) - r — how fast the S-curve rises; larger r = steeper transition - t₀ — the time at which the outcome is at its midpoint (inflection point)
We have weekly completion percentage data for a construction deliverable over 9 weeks.
Use summary() to examine the fitted coefficients, their
standard errors, and the residual standard error — a measure of how
closely the model matches the observed data.
summary(fit)
#>
#> Formula: y ~ logistic(x, K, r, t0)
#>
#> Parameters:
#> Estimate Std. Error t value Pr(>|t|)
#> K 84.3515 2.5142 33.550 4.67e-08 ***
#> r 1.0356 0.1380 7.505 0.000289 ***
#> t0 3.2520 0.1459 22.284 5.34e-07 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 4.148 on 6 degrees of freedom
#>
#> Number of iterations to convergence: 10
#> Achieved convergence tolerance: 1.49e-08A small residual standard error (relative to the response scale)
indicates a good fit. Coefficient t values with |t| > 2
are statistically meaningful.
plot_sigmoidal() plots the data, fitted curve, and
optional confidence bounds in a single call.
plot_sigmoidal(
fit, data, "time", "completion", "logistic",
conf_level = 0.95,
main = "Logistic Learning Curve - Completion Forecast",
xlab = "Week",
ylab = "Completion (%)"
)The shaded region is the 95% confidence band — the range within which the true fitted curve is likely to lie. Wider bands at the tails reflect greater uncertainty in extrapolated predictions.
Use predict_sigmoidal() to generate numeric forecasts,
including confidence bounds for specific future time points.
future_times <- seq(1, 12, length.out = 100)
predictions <- predict_sigmoidal(fit, future_times, "logistic", conf_level = 0.95)
knitr::kable(
tail(round(predictions, 1), 5),
caption = "Predicted completion (final 5 points)",
row.names = FALSE
)| x | pred | lwr | upr |
|---|---|---|---|
| 11.6 | 84.3 | 78.2 | 90.5 |
| 11.7 | 84.3 | 78.2 | 90.5 |
| 11.8 | 84.3 | 78.2 | 90.5 |
| 11.9 | 84.3 | 78.2 | 90.5 |
| 12.0 | 84.3 | 78.2 | 90.5 |
Different model types can produce different forecasts, especially in the tails. It is good practice to fit multiple models and compare their goodness-of-fit.
fit_logistic <- fit_sigmoidal(data, "time", "completion", "logistic")
fit_pearl <- fit_sigmoidal(data, "time", "completion", "pearl")
fit_gompertz <- fit_sigmoidal(data, "time", "completion", "gompertz")# Residual standard errors for comparison
rse <- function(fit) summary(fit)$sigma
comparison <- data.frame(
Model = c("Logistic", "Pearl", "Gompertz"),
Residual_StdError = round(c(rse(fit_logistic), rse(fit_pearl), rse(fit_gompertz)), 3)
)
knitr::kable(comparison, caption = "Model Fit Comparison (lower RSE = better fit)")| Model | Residual_StdError |
|---|---|
| Logistic | 4.148 |
| Pearl | 4.148 |
| Gompertz | 2.887 |
Now plot all three fits side by side:
x_seq <- seq(1, 12, length.out = 200)
pred_log <- predict_sigmoidal(fit_logistic, x_seq, "logistic")
pred_prl <- predict_sigmoidal(fit_pearl, x_seq, "pearl")
pred_gom <- predict_sigmoidal(fit_gompertz, x_seq, "gompertz")
# Base plot with observed data
plot(data$time, data$completion,
pch = 16, xlim = c(1, 12), ylim = c(0, 105),
main = "Learning Curve: Model Comparison",
xlab = "Week", ylab = "Completion (%)"
)
lines(pred_log$x, pred_log$pred, col = "steelblue", lwd = 2)
lines(pred_prl$x, pred_prl$pred, col = "tomato", lwd = 2, lty = 2)
lines(pred_gom$x, pred_gom$pred, col = "darkgreen", lwd = 2, lty = 3)
legend("bottomright",
legend = c("Logistic", "Pearl", "Gompertz"),
col = c("steelblue", "tomato", "darkgreen"),
lty = c(1, 2, 3), lwd = 2, bty = "n"
)Note: Logistic and Pearl share the same functional form and will produce identical fits on the same data. Gompertz has a different shape, its inflection point occurs earlier and the curve is asymmetric, making it better suited for processes that accelerate quickly early on.
The sigmoidal workflow in PRA:
fit_sigmoidal() — fit a model to observed
time-completion datasummary(fit) — inspect coefficient estimates and
goodness-of-fitpredict_sigmoidal() — generate numeric forecasts with
optional confidence boundsplot_sigmoidal() — visualize the fit and confidence
bandChoose the model type based on the shape of your data and theoretical expectations about the learning process.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.