logit() and logistic() functions in R

Published on

In statistics, a pair of standard functions logit() and logistic() are defined as follows:

\[ \begin{align*} \operatorname{logit}(p) &= \log\frac{p}{1-p}; \\ \operatorname{logistic}(x) &= \frac{1}{1+\exp(-x)}. \end{align*} \]

Given the ubiquity of these functions, it may be puzzling and frustrating for an R user that there are no pre-defined functions logit() and logistic() in R.

> logit(0.6)
Error in logit(0.6) : could not find function "logit"

Some CRAN packages define this function, and some users even import these packages for the sole reason to have access to logit() and/or logistic(). Others define them directly via log() and exp().

All this is unnecessary: the standard stats package actually defines these functions, just under different names. logit() and logistic() are the quantile and cumulative distribution functions for the logistic distribution, so in line with R’s conventions for probability distributions, they are called qlogis() and plogis(), respectively.

> qlogis(0.6) # logit
[1] 0.4054651
> plogis(0.4054651) # logistic
[1] 0.6

If you still prefer to use the familiar names logit() and logistic() in your code, simply include in your script

logit <- qlogis
logistic <- plogis

One advantage of using these standard functions over defining your own or importing some random CRAN package is that they can work on the log scale, by setting log.p = TRUE.

> qlogis(log(0.6), log.p = TRUE)
[1] 0.4054651

Working with log-probabilities is often necessary to avoid underflow, and implementing logit() and logistic() that work accurately on the log scale is not trivial; see Accurately Computing \(\log(1-\exp(-|a|))\) for the details. You can see how these functions are implemented in R in src/nmath/qlogis.c and src/nmath/plogis.c.

And while we’re at it, here’s another trick. Let’s say you are working with probabilities very close to 1. Then the appropriate representation is not \(\log p\) but \(\log (1-p)\). To convert a probability from a log-complement scale to the logit scale, use lower.tail = FALSE:

> qlogis(-3, log.p = TRUE, lower.tail = FALSE)
[1] 2.948931