Formatting P values
For printing ANOVA or regression coefficients tables
This post on R bloggers describes a handy function for formatting really small P values in ANOVA tables (more than 3 decimal places) with \(<0.001\). I find this easier to read when I need to present a formatted table, e.g. in teaching.
The original function doesn’t cover all ways of creating ANOVA tables in R
so I have extended the function to cover more cases. The fixp
function below will work for ANOVA tables (x
) generated by anova(lm(...))
and summary(aov(lm(...)))
, as well as the model coefficients table generated by coef(summary(lm(...)))
.
A function to format P values
fixp <- function(x, dig=3){
# Convert to a data frame
if(is.data.frame(x) | is.matrix(x)){
x <- as.data.frame(x)
} else {
x <- as.data.frame(x[[1]])
}
# Check column order
if(substr(names(x)[ncol(x)],1,2) != "Pr"){
warning("The name of the last column didn't start with Pr. This may indicate that p-values weren't in the last row, and thus, that this function is inappropriate.")
}
# Round P values to "dig" decimal places, default 3
x[,ncol(x)] <- round(x[,ncol(x)], dig)
#
for(i in 1:nrow(x)){
if(x[i,ncol(x)] == 0 & !is.na(x[i,ncol(x)])){
x[i,ncol(x)] <- paste0("<0.", paste0(rep(0,dig-1), collapse=""), "1")
}
}
x
}
The main modification to the original function is to expand the conversion of x
to a data frame to accept lists and matrices. summary(aov(lm(...)))
creates an object with class summary.aov
which is a list and the coefficients table is a matrix. Although anova(lm(...))
creates a data frame that will work with the function without a fatal error, the function anova
has its own way of “pretty” printing [to quote the help file] which is not compatible with the character vector in the P value column and thus will show a P value of 1. So forcing to a data frame is necessary. A minor modification is to ignore the NAs in the Residual row created by the data frame which would otherwise give an error.
The three decimal places for P values is coded into the function by default and can be changed by the dig
option. For example, dig = 1
will give you \(<0.1\). You can then call your ANOVA table and the fixp
function through knitr::kable()
or your favourite HTML/LaTeX table formatter. e.g. kable(fixp(anova(lm(...))), digits = ...)
. If you don’t want to print NAs, it’s probably better to use the options in your chosen formatting function - e.g. the knitr.kable.NA
option in kable
.