ceiling()
ceiling(x) The ceiling() function rounds numeric values up to the nearest integer (toward positive infinity). It is useful when you need a safe upper bound for pagination, batching, sampling, or bucket calculations.
Syntax
ceiling(x)
ceiling() is a C-level primitive, which makes it faster than R-level alternatives. The function accepts a single required argument x, which can be a scalar, a vector, or any numeric object. Because ceiling() is vectorized, passing a numeric vector returns a vector of the same length with each element rounded up individually, no sapply() or explicit loop needed. This vectorization makes ceiling() a natural fit for column-wise operations in data frames and tibbles.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
x | numeric | required | A numeric vector or scalar to round up |
Examples
Basic usage
# Round up positive numbers
ceiling(3.14)
# [1] 4
ceiling(3.0)
# [1] 3
ceiling(0.1)
# [1] 1
Rounding positive values is straightforward, but ceiling() also handles negative numbers with a behavior that surprises newcomers: it rounds toward positive infinity, not toward larger absolute values. For negative inputs this means rounding toward zero, so ceiling(-2.7) returns -2 rather than -3. This follows the mathematical definition — the ceiling is always the smallest integer greater than or equal to the input — but differs from what some users expect when they first encounter negative rounding. Being clear on this distinction prevents off-by-one bugs when data spans both positive and negative ranges.
Negative numbers
# Round up negative numbers (toward zero)
ceiling(-2.7)
# [1] -2
ceiling(-0.1)
# [1] 0
Because ceiling() is vectorized, you can apply it to an entire numeric vector in a single call without a loop or sapply(). Each element is rounded independently, and the result preserves the original length and names. This makes ceiling() a natural fit for dplyr pipelines: mutate(df, pages = ceiling(n_items / page_size)) applies the rounding across all rows in one pass. The underlying C implementation ensures this vectorized operation stays fast even on vectors with millions of entries, which matters when processing large datasets interactively.
Working with vectors
x <- c(1.1, 2.5, 3.9, -1.1, -2.5)
ceiling(x)
# [1] 2 3 4 -1 -2
The examples above cover the core rounding behavior, but ceiling() really proves its worth in everyday data work where exact integer counts are needed. Two of the most common application domains are pagination — splitting collections into fixed-size pages — and financial calculations where fractional amounts must round up to whole units. In both cases, ceiling() guarantees you allocate enough capacity: enough pages to display every item, or a high enough price to cover costs. The following patterns show how ceiling() handles these practical tasks with clean one-line expressions that stay readable during code review.
Common patterns
Pagination
# Number of pages needed
items <- 57
per_page <- 10
ceiling(items / per_page)
# [1] 6
Pagination is the textbook use case: dividing n items into groups of size k always needs rounding up. The expression ceiling(n / k) is concise and correct — it reads naturally and handles edge cases like n = 0 without extra conditional logic. In Shiny apps or REST API pagers, computing total pages from a record count and page size with ceiling() is a one-liner that any R developer can parse at a glance. This pattern also appears in batch processing, where jobs must be split into fixed-size chunks and the last chunk may be partially full.
Price calculations
# Round prices up to nearest dollar
prices <- c(9.99, 19.50, 29.01, 100.00)
ceiling(prices)
# [1] 10 20 30 100
Rounding prices up with ceiling() appears in retail and billing workflows where fractional currency units must resolve to whole cents or dollars. The function handles this cleanly because it applies element-wise across a price vector, converting 9.99 to 10 in a single call. For financial rounding where you need the nearest nickel or dime rather than the nearest integer, combine ceiling() with arithmetic: ceiling(prices * 20) / 20 rounds up to the nearest nickel. This scale-then-ceiling-then-unscale pattern generalizes to any rounding granularity — pennies, quarters, or custom increments.
Array indexing
# Get minimum sample size
n <- 100
sample_frac <- 0.03
ceiling(n * sample_frac)
# [1] 3
Determining minimum sample sizes is a statistical workflow where ceiling() prevents undersampling. When a power analysis computes a required sample size of 23.4 participants, using round() would return 23 and risk insufficient statistical power; ceiling(23.4) returns 24, the conservative choice. This same reasoning applies to allocating survey strata, determining batch sizes in A/B testing, and computing how many bootstrap resamples achieve a target precision. In each case, rounding up is the safe default.
Generating bin boundaries for histograms
When you need to create evenly spaced bins from a numeric range, ceiling() converts a continuous span into the smallest integer span that covers every value:
set.seed(42)
vals <- rnorm(1000, mean = 50, sd = 15)
bin_width <- 5
lo <- ceiling(min(vals) / bin_width) * bin_width
hi <- ceiling(max(vals) / bin_width) * bin_width
breaks <- seq(lo, hi, by = bin_width)
hist(vals, breaks = breaks, col = "steelblue", border = "white")
The pattern ceiling(min_val / w) * w finds the next multiple of w above the minimum, giving you a clean lower bound for binned displays. Combine this with a counterpart floor() call on the maximum and you get tidy axis limits and histogram break points that are multiples of a round number rather than arbitrary data-driven boundaries.
Using ceiling in dplyr pipelines
ceiling() works directly inside mutate() because the function is vectorized:
library(dplyr)
orders <- data.frame(
product = c("widget", "gadget", "doohickey", "widget", "gadget"),
quantity = c(7, 12, 5, 9, 14),
stringsAsFactors = FALSE
)
orders |>
mutate(boxes = ceiling(quantity / 4))
# product quantity boxes
# 1 widget 7 2
# 2 gadget 12 3
# 3 doohickey 5 2
# 4 widget 9 3
# 5 gadget 14 4
The expression ceiling(quantity / 4) computes how many boxes of size 4 are needed for each order. Because ceiling() is a C primitive, this scales to datasets with millions of rows without a noticeable performance hit. The same idiom works in data.table syntax: orders[, boxes := ceiling(quantity / 4)].
ceiling() vs floor() vs round() vs trunc()
ceiling() always rounds toward positive infinity, the ceiling of 2.1 is 3, not 2. It is the upper-rounding counterpart to floor().
Common uses for ceiling(): computing the number of pages needed to display n items at k per page (ceiling(n / k)), determining how many groups to create from a given number of items, and computing the number of batches needed for processing. The sample size calculation pattern ceiling(n * fraction) appears in survey design and testing, ensuring you sample at least the specified fraction even when rounding.
For generating nice axis limits in charts, ceiling(max(x)) gives the smallest integer that contains all values on the upper end. For computing how many complete intervals fit in a range, floor(range / interval) gives the count and ceiling() gives the count including partial intervals.
ceiling() is implemented as a C primitive and handles the full numeric range including negative numbers: ceiling(-2.3) is -2 (rounding toward zero for negative values).
ceiling() vs floor(), round(), and trunc()
ceiling() always rounds toward positive infinity — it returns the smallest integer greater than or equal to x. This means ceiling(-2.3) returns -2 (not -3), because -2 is greater than -2.3. This behavior distinguishes it from trunc(), which rounds toward zero: trunc(-2.3) also returns -2, but ceiling(2.3) returns 3 while trunc(2.3) also returns 2, so the two functions differ on positive non-integer values.
Common practical uses: ceiling(n / page_size) computes the number of pages needed to display n items at page_size items per page; ceiling(log2(n)) computes the minimum number of bits needed to represent n values. Both patterns arise from the need to round up to fit an exact amount of content or capacity.
For sample size calculations, ceiling() ensures you meet the minimum required: ceiling(qnorm(0.975)^2 * p * (1 - p) / margin^2) gives the minimum integer sample size. Statistical formulas typically produce non-integer results, and ceiling() converts them to the conservative (larger) integer rather than the optimistic (smaller) one that floor() or round() might give.
ceiling() is vectorized: ceiling(c(1.2, 2.5, 3.0, -1.7)) returns c(2, 3, 3, -1). It propagates NA, returns Inf for Inf input, and -Inf for -Inf input. Integer inputs pass through unchanged, since they are already integers.
Rounding to arbitrary precision
ceiling() rounds to the nearest integer, but you can round to any decimal place by scaling before and after:
# Round up to nearest 0.05 (nickel)
prices <- c(1.23, 4.57, 9.99, 12.34)
ceiling(prices * 20) / 20
# [1] 1.25 4.60 10.00 12.35
# Round up to one decimal place
ceiling(prices * 10) / 10
# [1] 1.3 4.6 10.0 12.4
# Round up to nearest 100
values <- c(123, 456, 789, 1234)
ceiling(values / 100) * 100
# [1] 200 500 800 1300
The general pattern is ceiling(x * m) / m where m = 1 / precision. For rounding to the nearest nickel, multiply by 20 (since there are 20 nickels in a dollar), apply ceiling(), then divide back. This same scale-then-round pattern works with floor() and round() for any desired granularity — pennies, dimes, hundreds, or thousands.