pubformat provides tools for converting numeric
statistical results into consistent, publication-ready character
output.
The package is designed around a simple principle:
Statistical analysis and statistical formatting should remain separate.
R or another statistical procedure produces the numeric result.
pubformat handles the reporting step without changing the
underlying statistical result, inferential decision, or substantive
interpretation.
The current development version includes formatting for:
format_p() converts numeric p-values into
publication-ready text.
The reporting threshold is strict. A value equal to .001
is retained, while a value below .001 is reported using
less-than notation.
Optional significance codes can be added when useful for tables or other compact displays.
format_p(0.048, sig = TRUE)
#> [1] "p = .048 *"
format_p(0.006, sig = TRUE)
#> [1] "p = .006 **"
format_p(0.0002, sig = TRUE)
#> [1] "p < .001 ***"Significance codes are determined from the original numeric p-value rather than its rounded display value.
format_ci() combines numeric lower and upper confidence
limits into publication-ready interval notation.
The confidence level can be changed.
Leading zeros are retained by default because the appropriate convention depends on the statistic being reported.
For statistics that cannot exceed 1 in absolute value, leading zeros can be omitted.
For Pearson correlations, format_r() provides a concise
formatter.
For Pearson, Spearman, or Kendall correlations,
format_cor() selects the appropriate reporting symbol.
format_cor(0.42, method = "pearson")
#> [1] "r = .42"
format_cor(0.42, method = "spearman")
#> [1] "ρ = .42"
format_cor(0.42, method = "kendall")
#> [1] "τ = .42"format_cor() formats an existing coefficient. It does
not calculate the correlation itself.
For example:
format_percent() interprets numeric values as
proportions by default.
Values that are already expressed as percentages can be identified explicitly.
This distinction prevents accidental rescaling.
The function is vectorized.
Values supplied with input = "percent" may also be
negative or greater than 100, which can be useful for quantities such as
percent change.
format_t() and format_f() convert
already-computed test statistics and their degrees of freedom into
publication-ready text.
These functions do not perform statistical tests. They format numeric results produced by R or another statistical procedure.
format_t() formats a t statistic together with its
degrees of freedom.
Negative statistics are preserved.
Fractional degrees of freedom are also supported.
A p-value can be supplied directly.
The p-value is formatted internally using
format_p().
format_t(
statistic = c(3.10, 3.20),
df = c(40, 40),
p = c(0.001, 0.0009)
)
#> [1] "t(40) = 3.10, p = .001" "t(40) = 3.20, p < .001"This preserves the distinction between p = .001 and
p < .001.
format_f() formats an F statistic together with
numerator and denominator degrees of freedom.
Fractional degrees of freedom are retained when present.
A p-value can be included in the same result.
Very small p-values retain the behavior of
format_p().
This is useful for converting ANOVA or mixed-model output into manuscript-ready text.
Plain character output is the default because the R console does not render italics.
For documents that support markup, format_t() and
format_f() can return Markdown, HTML, or LaTeX
formatting.
The effect-size functions accept already-computed estimates and optional confidence intervals.
They do not calculate the effect size and do not classify the result as small, medium, or large.
format_d() formats Cohen’s d.
Confidence limits can be included.
Negative estimates and confidence limits are preserved.
For output formats that support markup, the Latin statistical symbol can also be styled.
format_g() follows the same structure for Hedges’ g.
Styled output is also available.
format_eta2() automatically provides the eta-squared
symbol.
A confidence interval can be supplied.
Eta squared is bounded between 0 and 1, so leading zeros are omitted.
format_partial_eta2() automatically supplies the partial
eta-squared notation.
The returned character output contains the Greek eta, subscript p, and superscript 2 directly.
This avoids the need to manually insert the notation in a word processor.
format_omega2() automatically supplies the omega-squared
symbol.
Confidence limits can be supplied.
Negative omega-squared estimates are preserved rather than automatically changed to zero.
Likewise, negative confidence-limit estimates remain unchanged.
This reflects the package’s role as a formatter rather than a statistical decision-making tool.
Consider a simple linear model using the built-in mtcars
data.
model <- lm(mpg ~ wt, data = mtcars)
summary(model)
#>
#> Call:
#> lm(formula = mpg ~ wt, data = mtcars)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -4.5432 -2.3647 -0.1252 1.4096 6.8727
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 37.2851 1.8776 19.858 < 2e-16 ***
#> wt -5.3445 0.5591 -9.559 1.29e-10 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 3.046 on 30 degrees of freedom
#> Multiple R-squared: 0.7528, Adjusted R-squared: 0.7446
#> F-statistic: 91.38 on 1 and 30 DF, p-value: 1.294e-10The analysis produces numeric statistical results. Those values can then be extracted and formatted separately.
coef_table <- summary(model)$coefficients
t_value <- coef_table["wt", "t value"]
p_value <- coef_table["wt", "Pr(>|t|)"]
df_value <- df.residual(model)
format_t(
statistic = t_value,
df = df_value,
p = p_value
)
#> [1] "t(30) = -9.56, p < .001"Effect sizes follow the same pattern: calculate the effect size using
the appropriate statistical method and then pass the resulting estimate
and optional confidence limits to a pubformat
formatter.
For example, if an analysis has already produced:
the reporting step is:
The workflow is therefore:
statistical analysis
|
v
numeric statistical results
|
v
pubformat
|
v
publication-ready output
pubformat does not replace statistical analysis
functions. Its purpose is to make the final reporting step more
consistent, reproducible, and convenient.
The formatting functions are designed to accept vectors, which makes them useful when preparing tables or formatting several results at once.
format_d(
d = c(0.52, -0.31, 1.14),
lower = c(0.18, -0.62, 0.80),
upper = c(0.86, 0.00, 1.48)
)
#> [1] "d = 0.52, 95% CI [0.18, 0.86]" "d = -0.31, 95% CI [-0.62, 0.00]"
#> [3] "d = 1.14, 95% CI [0.80, 1.48]"format_omega2(
omega2 = c(0.08, -0.02, 0.31),
lower = c(0.02, -0.06, 0.20),
upper = c(0.15, 0.02, 0.42)
)
#> [1] "ω² = .08, 95% CI [.02, .15]" "ω² = -.02, 95% CI [-.06, .02]"
#> [3] "ω² = .31, 95% CI [.20, .42]"Missing values are preserved rather than silently converted into text.
The package separates three concepts that can otherwise become conflated:
lm(), cor(), confint(),
or functions from other statistical packages.pubformat after the analysis is complete.This separation allows results to be formatted consistently without changing the values on which statistical conclusions are based.
The same principle applies to effect sizes. pubformat
does not automatically classify an effect as small, medium, or large.
Instead, it preserves the supplied estimate and, when available, its
confidence interval.
This keeps reporting reproducible while leaving substantive interpretation with the researcher.