Search Shortcut cmd + k | ctrl + k

A statistical computing toolkit for DuckDB, with descriptive statistics, hypothesis tests, R-style distribution functions (d/p/q/r), linear and generalized linear models with robust and cluster-robust standard errors, linear hypotheses and estimated marginal means, grammar-of-graphics charts (VISUALIZE to Vega-Lite), and readers and writers for SAS, SPSS and Stata files, all in SQL.

Maintainer(s): caerbannogwhite

Compatibility Matrix

This table covers all DuckDB releases that have not reached end-of-life, including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.

Platform 1.4.4 1.4.5 1.5.5 1.5.6 2.0.0
Linux AMD64
Linux ARM64
macOS AMD64
macOS ARM64
Windows AMD64
Windows ARM64
WebAssembly

Installing and Loading

INSTALL stats_duck FROM community;
LOAD stats_duck;

Example

-- R-style distribution functions (d/p/q/r for 15+ families):
D SELECT pnorm(1.96) AS p, qt(0.975, 30) AS t_crit, dpois(3, 2.5) AS pmf;
┌────────────────────┬────────────────────┬─────────────────────┐
│         p          │       t_crit       │         pmf         │
│       double       │       double       │       double        │
├────────────────────┼────────────────────┼─────────────────────┤
│ 0.9750021048517796 │ 2.0422724563012373 │ 0.21376301724973648 │
└────────────────────┴────────────────────┴─────────────────────┘

-- OLS regression as an aggregate (one model per GROUP BY), with robust SEs.
-- vcov: 'const' | 'HC0'..'HC3' | 'CR0'/'CR1' (cluster-robust, + a cluster key).
D SELECT (c).term, (c).estimate, (c).std_error
  FROM (
    SELECT unnest((lm_fit(y, [x1, x2], 'HC1')).coefficients) AS c
    FROM my_data
  );

-- A generalized linear model as an aggregate: poisson with a log link.
-- Families: gaussian, binomial, poisson, gamma. Options (link, vcov,
-- intercept, weights, offset, cluster) go in a trailing STRUCT.
D SELECT (c).term, (c).estimate, (c).std_error
  FROM (
    SELECT unnest((glm_fit(events, [x1, x2], 'poisson', {'vcov': 'HC1'})).coefficients) AS c
    FROM my_data
  );

-- A clinical "Table 1" over mixed variable types, with between-group tests:
D SELECT * FROM table_one('patients', variables := ['age', 'sex', 'bmi'], by := ['arm']);

-- Grammar-of-graphics: turn a query into a Vega-Lite spec (+ the SQL to feed it):
D VISUALIZE wt AS x, mpg AS y FROM cars DRAW point;

About stats_duck

The Stats Duck

A statistical computing toolkit that brings common statistical work into DuckDB SQL. Every function is a streaming aggregate or a scalar function, so it runs inside GROUP BY and window frames over large tables, and the same build runs in DuckDB-WASM in the browser.

What is included

  • Descriptive statistics: summary_stats, table_one (the clinical "Table 1"), corr_matrix, meta.
  • Hypothesis tests: one-sample, two-sample and paired t-tests, one-way ANOVA, chi-square, Mann-Whitney, Wilcoxon signed-rank, Kolmogorov-Smirnov, Shapiro-Wilk, Anderson-Darling, Jarque-Bera, and correlation tests (Pearson, Spearman, Kendall).
  • Distribution functions: R-style d/p/q/r quartets for 15+ families (normal, t, chi-square, F, gamma, beta, exponential, Weibull, log-normal, Poisson, negative binomial, hypergeometric, and more), plus ptukey and qtukey for the studentized range.
  • Regression: the lm and lm_summary table functions and the lm_fit aggregate (one model per GROUP BY) with classical, HC0 to HC3 heteroskedasticity-consistent, and CR0/CR1 cluster-robust standard errors. A rank-deficient design is fitted with the aliased columns reported NULL, as R does. glm_fit fits generalized linear models by iteratively reweighted least squares for the gaussian, binomial, poisson and gamma families and their links, with the same covariance options.
  • Inference after a fit: lin_hyp tests a general linear hypothesis L·β = 0 on any fit's coefficients and covariance (contrasts, joint tests, Type III sums of squares). emmeans computes estimated marginal means and their pairwise differences, with Tukey, Bonferroni, Holm, Hochberg, BH or BY adjustment.
  • Grammar of graphics: VISUALIZE … DRAW <mark> returns a Vega-Lite v5 spec plus the SQL needed to feed it.
  • Statistical file formats: readers and writers for SAS (.sas7bdat, .xpt), SPSS (.sav, .por) and Stata files, via ReadStat.
  • Resampling and correction: bootstrap, and adjust_p with the Bonferroni, Holm, Hochberg, BH, BY or no correction.

Full function reference: https://github.com/KoliStat/the-stats-duck.

Added Functions

function_name function_type description comment examples
adjust_p scalar Multiple-testing correction over a list of p-values (bonferroni, holm, hochberg, BH/fdr, BY, or none). NULL [SELECT adjust_p([0.01, 0.04, 0.20], 'holm')]
anderson_darling aggregate Anderson-Darling normality test against the fitted normal (n >= 8). NULL [SELECT anderson_darling(x) FROM samples]
anova_oneway aggregate One-way ANOVA across the groups of a categorical column. NULL [SELECT anova_oneway(yield, variety) FROM crops]
bin_edges aggregate Automatic histogram bin edges — sturges (default), fd, scott, sqrt, rice, or auto. NULL [SELECT bin_edges(price) FROM sales]
bin_label scalar Label of the bin containing x, given an edge vector (typically from bin_edges). NULL [SELECT bin_label(7.5, [0.0, 5.0, 10.0])]
bootstrap aggregate With-replacement bootstrap of a statistic (mean, median, sum, stddev, variance, min, max); returns a LIST of n_iters resampled values. NULL [SELECT bootstrap(revenue, 'mean', 1000, 42) FROM sales]
chisq_goodness_of_fit aggregate Chi-square goodness-of-fit against a uniform distribution over the observed categories. NULL [SELECT chisq_goodness_of_fit(die_face) FROM rolls]
chisq_independence aggregate Chi-square test of independence between two categorical columns. NULL [SELECT chisq_independence(sex, outcome) FROM patients]
corr_matrix table Long-format pairwise correlation matrix over a table's numeric columns (pearson, spearman, or kendall). NULL [SELECT * FROM corr_matrix('iris', variables := ['sepal_length', 'petal_length'])]
dbeta scalar Beta distribution PDF on [0, 1]. NULL [SELECT dbeta(0.5, 2.0, 3.0)]
dchisq scalar Chi-square distribution PDF. NULL [SELECT dchisq(3.0, 2)]
dexp scalar Exponential distribution PDF; rate defaults to 1. NULL [SELECT dexp(1.0)]
df scalar F distribution PDF. NULL [SELECT df(1.0, 3, 12)]
dgamma scalar Gamma distribution PDF; rate defaults to 1. NULL [SELECT dgamma(2.0, 3.0)]
dhyper scalar Hypergeometric PMF (m successes, n failures, k draws). NULL [SELECT dhyper(1, 5, 10, 4)]
dlnorm scalar Log-normal distribution PDF; defaults meanlog = 0, sdlog = 1. NULL [SELECT dlnorm(1.0)]
dnbinom scalar Negative-binomial PMF: failures before size successes. NULL [SELECT dnbinom(2, 5, 0.5)]
dnorm scalar Normal distribution PDF; defaults mean = 0, sd = 1. NULL [SELECT dnorm(0.0)]
dpois scalar Poisson PMF (discrete). NULL [SELECT dpois(3, 2.5)]
dt scalar Student's t distribution PDF. NULL [SELECT dt(0.5, 10)]
dweibull scalar Weibull distribution PDF; scale defaults to 1. NULL [SELECT dweibull(1.0, 2.0)]
emmeans scalar Estimated marginal means of a fit: each grid row's mean L·β with its standard error, t, p and confidence limits, every pairwise difference, and a multiplicity adjustment over that family ('tukey', 'bonferroni', 'holm', 'hochberg', 'BH' or 'fdr', 'BY', 'none'). alpha defaults to 0.05 and adjust to 'tukey'. Under 'tukey' a df that is not an integer and is below 4 makes the adjustment accurate to about 1e-5 rather than 1e-12. Nothing else about the function is affected by that limit. NULL [SELECT emmeans([[1, 0, 0], [0, 1, 0], [0, 0, 1]], [2.0, 6.0, 6.0], [0.8889,0,0, 0,0.8889,0, 0,0,0.8889], 6.0)]
glm_fit aggregate Generalized linear model aggregate — one model per group, fitted by iteratively reweighted least squares over the gaussian, binomial, poisson and gamma families. The binomial response is a proportion and the weights option is the trial count, so 7 of 10 is y = 0.7 with weight 10. Options go in one trailing STRUCT read by field name: 'link', 'vcov' ('const', 'HC0'–'HC3', 'CR0'/'CR1'), 'intercept', 'weights', 'offset' and 'cluster'. z_statistic uses a normal reference for every family, including gaussian and gamma where R uses a t. NULL [SELECT glm_fit(y, [x1, x2], 'binomial', {'vcov': 'HC1'}) FROM data]
jarque_bera aggregate Jarque-Bera normality test (skewness + kurtosis). NULL [SELECT jarque_bera(returns) FROM prices]
kendall_test aggregate Kendall's tau-b rank correlation (tie-corrected, normal approximation). NULL [SELECT kendall_test(x, y) FROM pairs]
ks_test_1samp aggregate One-sample Kolmogorov-Smirnov normality test against the fitted normal. NULL [SELECT ks_test_1samp(x) FROM samples]
ks_test_2samp aggregate Two-sample Kolmogorov-Smirnov test for equality of distributions. NULL [SELECT ks_test_2samp(a, b) FROM t]
lin_hyp scalar General linear hypothesis L·β = 0 against a fit: per-constraint estimates with standard errors, plus the joint sum of squares, F and chi-square. NULL [SELECT lin_hyp([[0, 1, -1]], [10.0, 2.0, -1.0], [4.3,-0.14,-0.52, -0.14,0.017,0.0023, -0.52,0.0023,0.101], 7.46, 9.0)]
lm table OLS regression over a table: per-term coefficient estimates for y ~ x (or a formula). NULL [SELECT * FROM lm('cars', y := 'mpg', x := ['wt', 'hp'])]
lm_fit aggregate OLS regression aggregate — one model per group; vcov 'const', 'HC0'..'HC3', or 'CR0'/'CR1' with a VARCHAR cluster key. NULL [SELECT lm_fit(y, [x1, x2], 'HC1') FROM data]
lm_summary table OLS model-level summary (R-squared, F, sigma) for y ~ x over a table. NULL [SELECT * FROM lm_summary('cars', y := 'mpg', x := ['wt', 'hp'])]
mann_whitney_u aggregate Mann-Whitney U test (Wilcoxon rank-sum) for two independent samples. NULL [SELECT mann_whitney_u(treatment, control) FROM outcomes]
meta table Column-level profile of a table: one row per column with a kind classification and light statistics. NULL [SELECT * FROM meta('patients')]
pbeta scalar Beta distribution CDF. NULL [SELECT pbeta(0.5, 2.0, 3.0)]
pchisq scalar Chi-square distribution CDF. NULL [SELECT pchisq(3.84, 1)]
pearson_test aggregate Pearson correlation with significance test and confidence interval. NULL [SELECT pearson_test(height, weight) FROM people]
pexp scalar Exponential distribution CDF; rate defaults to 1. NULL [SELECT pexp(1.0)]
pf scalar F distribution CDF. NULL [SELECT pf(4.47, 3, 12)]
pgamma scalar Gamma distribution CDF; rate defaults to 1. NULL [SELECT pgamma(2.0, 3.0)]
phyper scalar Hypergeometric CDF. NULL [SELECT phyper(1, 5, 10, 4)]
plnorm scalar Log-normal distribution CDF; defaults meanlog = 0, sdlog = 1. NULL [SELECT plnorm(1.0)]
pnbinom scalar Negative-binomial CDF. NULL [SELECT pnbinom(2, 5, 0.5)]
pnorm scalar Normal distribution CDF; defaults mean = 0, sd = 1. NULL [SELECT pnorm(1.96)]
poibin_cdf scalar Poisson-binomial CDF: P(X <= k) for a sum of independent Bernoulli trials with the given success probabilities. NULL [SELECT poibin_cdf([0.2, 0.5, 0.9], 2)]
ppois scalar Poisson CDF. NULL [SELECT ppois(3, 2.5)]
pt scalar Student's t distribution CDF. NULL [SELECT pt(2.04, 30)]
ptukey scalar Studentized range distribution CDF for k means on df degrees of freedom. A df that is not an integer and is below 4 is accurate to about 1e-5 rather than 1e-12. NULL [SELECT ptukey(3.0, 3, 10)]
pweibull scalar Weibull distribution CDF; scale defaults to 1. NULL [SELECT pweibull(1.0, 2.0)]
qbeta scalar Beta distribution quantile. NULL [SELECT qbeta(0.95, 2.0, 3.0)]
qchisq scalar Chi-square distribution quantile. NULL [SELECT qchisq(0.95, 1)]
qexp scalar Exponential distribution quantile (closed form); rate defaults to 1. NULL [SELECT qexp(0.95)]
qf scalar F distribution quantile. NULL [SELECT qf(0.95, 3, 12)]
qgamma scalar Gamma distribution quantile; rate defaults to 1. NULL [SELECT qgamma(0.95, 3.0)]
qhyper scalar Hypergeometric quantile. NULL [SELECT qhyper(0.95, 5, 10, 4)]
qlnorm scalar Log-normal distribution quantile; defaults meanlog = 0, sdlog = 1. NULL [SELECT qlnorm(0.95)]
qnbinom scalar Negative-binomial quantile (integer search). NULL [SELECT qnbinom(0.95, 5, 0.5)]
qnorm scalar Normal distribution quantile; defaults mean = 0, sd = 1. NULL [SELECT qnorm(0.975)]
qpois scalar Poisson quantile (integer search). NULL [SELECT qpois(0.95, 2.5)]
qt scalar Student's t distribution quantile. NULL [SELECT qt(0.975, 30)]
qtukey scalar Studentized range distribution quantile, the Tukey HSD critical value, for k means on df degrees of freedom. A df that is not an integer and is below 4 is accurate to about 1e-5 rather than 1e-12. NULL [SELECT qtukey(0.95, 3, 10)]
qweibull scalar Weibull distribution quantile (closed form); scale defaults to 1. NULL [SELECT qweibull(0.95, 2.0)]
rbeta scalar Random beta sample per row (volatile). NULL [SELECT rbeta(2.0, 3.0) FROM range(5)]
rchisq scalar Random chi-square sample per row (volatile). NULL [SELECT rchisq(2.0) FROM range(5)]
read_stat table Read SAS (.sas7bdat/.xpt), SPSS (.sav/.por), or Stata (.dta) files as a table. NULL [SELECT * FROM read_stat('data.sav')]
read_stat_metadata table Variable-level metadata (labels, formats, value labels) of a SAS/SPSS/Stata file. NULL [SELECT * FROM read_stat_metadata('data.sav')]
rexp scalar Random exponential sample per row (volatile); rate defaults to 1. NULL [SELECT rexp() FROM range(5)]
rf scalar Random F-distribution sample per row (volatile). NULL [SELECT rf(3.0, 12.0) FROM range(5)]
rgamma scalar Random gamma sample per row (volatile); rate defaults to 1. NULL [SELECT rgamma(2.0) FROM range(5)]
rhyper scalar Random hypergeometric sample per row (volatile). NULL [SELECT rhyper(5.0, 10.0, 4.0) FROM range(5)]
rlnorm scalar Random log-normal sample per row (volatile); defaults meanlog = 0, sdlog = 1. NULL [SELECT rlnorm() FROM range(5)]
rnbinom scalar Random negative-binomial sample per row (volatile). NULL [SELECT rnbinom(5.0, 0.5) FROM range(5)]
rnorm scalar Random normal sample per row (volatile); defaults mean = 0, sd = 1. NULL [SELECT rnorm() FROM range(5)]
rpois scalar Random Poisson sample per row (volatile). NULL [SELECT rpois(2.5) FROM range(5)]
rt scalar Random Student's t sample per row (volatile). NULL [SELECT rt(10.0) FROM range(5)]
rweibull scalar Random Weibull sample per row (volatile); scale defaults to 1. NULL [SELECT rweibull(1.5) FROM range(5)]
shapiro_wilk aggregate Shapiro-Wilk normality test (Royston AS R94; n in [3, 5000]). NULL [SELECT shapiro_wilk(residual) FROM fits]
sign_test_1samp aggregate Sign test of the median against a hypothesized value (default 0). NULL [SELECT sign_test_1samp(delta, 0.0) FROM changes]
sign_test_paired aggregate Paired sign test on per-row differences. NULL [SELECT sign_test_paired(before, after) FROM measurements]
spearman_test aggregate Spearman rank correlation with significance test. NULL [SELECT spearman_test(rank_a, rank_b) FROM scores]
summary_stats aggregate Descriptive summary: n, missing, mean, sd, variance, quartiles, skewness, kurtosis, mode. NULL [SELECT summary_stats(age) FROM patients]
table_one table Clinical 'Table 1': long-format descriptives for mixed variable types, optionally stratified with between-group tests. NULL [SELECT * FROM table_one('patients', variables := ['age', 'sex'], by := ['arm'])]
ttest_1samp aggregate One-sample t-test of the column mean against a hypothesized value (default mu = 0). NULL [SELECT ttest_1samp(reaction_ms, 250.0) FROM trials]
ttest_2samp aggregate Two-sample t-test — Welch's by default, Student's pooled with equal_var := true. NULL [SELECT ttest_2samp(score_a, score_b) FROM results]
ttest_paired aggregate Paired t-test on per-row differences. NULL [SELECT ttest_paired(before, after) FROM measurements]
visualize_mark_v1_area scalar Internal VISUALIZE support function: mark registry entry for DRAW area. Not intended for direct use. NULL  
visualize_mark_v1_bar scalar Internal VISUALIZE support function: mark registry entry for DRAW bar. Not intended for direct use. NULL  
visualize_mark_v1_boxplot scalar Internal VISUALIZE support function: mark registry entry for DRAW boxplot. Not intended for direct use. NULL  
visualize_mark_v1_density scalar Internal VISUALIZE support function: mark registry entry for DRAW density. Not intended for direct use. NULL  
visualize_mark_v1_errorband scalar Internal VISUALIZE support function: mark registry entry for DRAW errorband. Not intended for direct use. NULL  
visualize_mark_v1_errorbar scalar Internal VISUALIZE support function: mark registry entry for DRAW errorbar. Not intended for direct use. NULL  
visualize_mark_v1_heatmap scalar Internal VISUALIZE support function: mark registry entry for DRAW heatmap. Not intended for direct use. NULL  
visualize_mark_v1_histogram scalar Internal VISUALIZE support function: mark registry entry for DRAW histogram. Not intended for direct use. NULL  
visualize_mark_v1_line scalar Internal VISUALIZE support function: mark registry entry for DRAW line. Not intended for direct use. NULL  
visualize_mark_v1_point scalar Internal VISUALIZE support function: mark registry entry for DRAW point. Not intended for direct use. NULL  
visualize_mark_v1_regression scalar Internal VISUALIZE support function: mark registry entry for DRAW regression. Not intended for direct use. NULL  
visualize_mark_v1_rule scalar Internal VISUALIZE support function: mark registry entry for DRAW rule. Not intended for direct use. NULL  
visualize_mark_v1_text scalar Internal VISUALIZE support function: mark registry entry for DRAW text. Not intended for direct use. NULL  
visualize_mark_v1_tick scalar Internal VISUALIZE support function: mark registry entry for DRAW tick. Not intended for direct use. NULL  
visualize_mark_v1_violin scalar Internal VISUALIZE support function: mark registry entry for DRAW violin. Not intended for direct use. NULL  
wilcoxon_signed_rank aggregate Wilcoxon signed-rank test on paired differences. NULL [SELECT wilcoxon_signed_rank(before, after) FROM measurements]

Overloaded Functions

This extension does not add any function overloads.

Added Types

This extension does not add any types.

Added Settings

name description input_type scope aliases typed_value
temp_directory Set the directory to which temporary files are written. VARCHAR GLOBAL [] post.db.tmp
© 2026 DuckDB Foundation, Amsterdam NL
DuckDB Home Code of Conduct Trademark Use Blog