Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

pnorm in R: Syntax, lower.tail and Worked Examples

How pnorm works in R: syntax, lower.tail and log.p, vectorised use, and a two-tailed p-value from a z-score, with worked examples from the R manual.

Written and maintained by CASRAI Editorial Board

Last updated

pnorm() is the R function that returns the cumulative distribution function (CDF) of the normal distribution: given a quantile q, it returns the probability that a normal random variable is at most q. The call is pnorm(q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE). This guide covers the arguments that decide whether you get the right tail or the left, how to use pnorm on whole columns of z-scores, and how to turn a z-statistic into a two-tailed p-value with 2*pnorm(-abs(z)).

What pnorm is used for in research

In R’s documentation pnorm sits in the “Normal” family with dnorm (density), qnorm (quantile function) and rnorm (random generation). The R manual An Introduction to R describes the naming rule: prefix the distribution name with d for the density, p for the CDF, q for the quantile function (and r for random simulation). pnorm is therefore the “p” member for the normal distribution.

Typical research uses:

  • Finding the proportion of a normally distributed measurement below, above or between cut-offs.
  • Converting a z-statistic into a p-value (see how to find a p-value from a z-score).
  • Overlaying a fitted normal CDF on an empirical distribution; the manual’s own example draws pnorm(x, mean = mean(long), sd = sqrt(var(long))) as a line on a plot.

For the concept behind the function, see the cumulative distribution function and the probability distribution function of the normal distribution. For the reverse direction, from a probability back to a quantile, use qnorm in R.

Install or access (official source only)

pnorm belongs to the stats package, which is part of the base distribution of R and is attached by default, so nothing beyond R itself needs to be installed and no library() call is needed. Download R from the Comprehensive R Archive Network, cran.r-project.org, which lists downloads for each operating system. As of 2026-10-29 the CRAN Windows page offers R 4.6.1 (last change 2026-06-26). Once R is running, ?pnorm opens the help page.

Step-by-step: compute a normal probability with pnorm

The examples use a variable that is normally distributed with mean 100 and standard deviation 15.

  1. Standard normal, left tail. With mean and sd omitted, R uses 0 and 1. pnorm(0) returns 0.5, because half of the standard normal distribution lies at or below zero. pnorm(1.96) returns 0.9750021.
  2. Your own mean and standard deviation. pnorm(115, mean = 100, sd = 15) returns 0.8413447: the probability that the variable is at most 115, which is one standard deviation above the mean.
  3. Right tail. pnorm(130, mean = 100, sd = 15, lower.tail = FALSE) returns 0.02275013, the probability that the variable exceeds 130.
  4. Between two values. Subtract two CDF values: pnorm(130, 100, 15) - pnorm(70, 100, 15) returns 0.9544997, the probability of falling between 70 and 130 (within two standard deviations of the mean).
  5. Two-tailed p-value from a z-statistic. For a test statistic z that is standard normal under the null hypothesis, 2 * pnorm(-abs(z)) doubles the probability in the tail beyond |z|. For z = 2.5 this gives 2 * pnorm(-2.5) = 0.01241933. The doubling idiom is the same one the R manual shows for a t-distribution, 2*pt(-2.43, df = 13).

Output and how to read it

lower.tail: left tail or right tail

The documentation defines lower.tail as a logical: if TRUE (the default), probabilities are P[X ≤ x]; otherwise they are P[X > x]. The two calls therefore always add to one: pnorm(q) + pnorm(q, lower.tail = FALSE) equals 1. Writing pnorm(q, lower.tail = FALSE) is the direct way to get an upper-tail probability, and it is the form to prefer over 1 - pnorm(q) when the upper tail is very small.

log.p: probabilities on the log scale

With log.p = TRUE the function returns the logarithm of the probability. The documentation’s own examples use it. For a far-out quantile such as pnorm(-10), the probability is about 7.6e-24, and pnorm(-10, log.p = TRUE) returns its natural logarithm, about -53.23. Use this when you need to add or compare very small probabilities, for example in likelihood work.

Vectorised input

The Value section of the manual states that the result has the length of the longest numeric argument and that numerical arguments are recycled. Only the first element of each logical argument (lower.tail, log.p) is used. Two consequences for data work:

  • pnorm(c(-1.96, 0, 1.96)) returns three probabilities (0.0249979, 0.5, 0.9750021) in one call, so you can apply it directly to a column of z-scores, for example df$p_lower <- pnorm(df$z).
  • mean and sd may also be vectors, so one call can evaluate each row against its own normal distribution.

pnorm and qnorm are inverses

qnorm(pnorm(1.96)) returns 1.96 again. Use pnorm when you start from a quantile and want a probability; use qnorm when you start from a probability. Both are documented on the same help page.

Troubleshooting

  • NaN returned. The manual states that a negative sd is an error and gives NaN. Check that you did not pass a variance where a standard deviation is expected: sd is the standard deviation, so use sqrt(variance).
  • sd = 0. The documentation says this gives the limit as sd decreases to 0, a point mass at mu: the CDF jumps from 0 to 1 at the mean.
  • Result looks like 1 – the answer you expected. You have the wrong tail. Left-tail probabilities are the default; add lower.tail = FALSE for P[X > x].
  • Upper-tail probability prints as 0 or 1. At extreme quantiles a value near 1 cannot hold the small tail probability. Use lower.tail = FALSE or log.p = TRUE rather than subtracting from 1.
  • Wrong p-value from a z-statistic. pnorm(z) is the left-tail probability only. A two-tailed p-value needs 2 * pnorm(-abs(z)).

Free alternatives

The same normal CDF is available outside R. Both tools below are free and open source.

Tool Equivalent call Notes
R (base stats) pnorm(q, mean, sd) Reference implementation described here; lower.tail and log.p built in.
Python, SciPy scipy.stats.norm.cdf(x, loc, scale) The normal distribution object in scipy.stats; loc is the mean and scale the standard deviation.
Python standard library statistics.NormalDist(mu, sigma).cdf(x) No extra package; left-tail probability only.

For MATLAB see the normal distribution in MATLAB.

FAQ

What does pnorm do in R?

It returns the cumulative probability of the normal distribution: P[X ≤ q] by default, or P[X > q] with lower.tail = FALSE.

What is the difference between pnorm, dnorm and qnorm?

dnorm gives the density at a point, pnorm gives the cumulative probability up to a quantile, and qnorm inverts pnorm to return the quantile for a given probability. rnorm generates random values. See qnorm in R for the inverse.

How do I use pnorm in R to get a p-value?

For a standard normal test statistic z, a one-tailed upper p-value is pnorm(z, lower.tail = FALSE) and a two-tailed p-value is 2 * pnorm(-abs(z)). See how to find a p-value from a z-score, and the inverse normal for critical values.

How do I calculate the probability between two values?

Subtract the two CDF values: pnorm(b, mean, sd) - pnorm(a, mean, sd) for a < b.

What is the default mean and standard deviation in pnorm?

If mean or sd is omitted, R uses 0 and 1, the standard normal distribution.

Sources (official documentation)

  • R Core Team, “The Normal Distribution” help page for stats::Normal (stat.ethz.ch R manual), checked 2026-10-29. The page cites Cody (1993) as the basis of pnorm.
  • R Core Team, An Introduction to R, section “Probability distributions” (cran.r-project.org), checked 2026-10-29.
  • CRAN, R for Windows download page (cran.r-project.org/bin/windows/base), checked 2026-10-29.
  • SciPy documentation, scipy.stats.norm (docs.scipy.org), checked 2026-10-29.

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about pnorm in R: Syntax, lower.tail and Worked Examples

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →