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

Sample in R: sample() Function, Syntax and Data Frame Rows

sample() syntax and arguments in R, sampling data frame rows in base R and dplyr slice_sample(), and replacing superseded sample_n().

Written and maintained by CASRAI Editorial Board

Last updated

Short answer: sample(x, size, replace = FALSE, prob = NULL) in base R draws size items from the vector x. To draw rows from a data frame, sample row numbers and use them to index the frame, or call dplyr’s slice_sample(). This page is for researchers who need a random subset of a vector or a data set and want to know exactly what each argument does.

The code below follows the base R and dplyr reference pages listed under Sources. Random draws differ between runs and between R versions, so the examples show code, not output. To get the same draw every time, set a seed first, as explained in random number generation in R.

What sample() is used for in research

Researchers use sample() to draw a simple random subset for checking or auditing records, to split data into training and test sets, to shuffle order, and to resample with replacement as the first step of a bootstrap. Which draw is appropriate depends on the design; see sampling methods for the design side. The function only draws; it does not tell you whether a sample is representative.

Install or access

sample() and sample.int() are part of base R, so nothing needs installing. R is distributed through CRAN (cran.r-project.org); the R manuals there were for R 4.6.2 (2026-10-29) when read on 2026-11-07. slice_sample(), sample_n() and sample_frac() belong to the dplyr package, installed once with install.packages("dplyr") and loaded each session with library(dplyr).

Step-by-step: sample() on a vector

Syntax and arguments

The documented usage is sample(x, size, replace = FALSE, prob = NULL) and sample.int(n, size = n, replace = FALSE, prob = NULL, useHash = ...).

Argument Meaning in the base R documentation
x Either a vector of one or more elements to choose from, or a positive integer.
size A non-negative integer giving the number of items to choose.
replace Whether sampling is with replacement. Default FALSE.
prob A vector of probability weights for the elements being sampled. Default NULL.
  1. Set a seed if you need to reproduce the draw: set.seed(2026).
  2. Draw without replacement: x <- 1:12 then sample(x, 5) returns five distinct elements of x.
  3. Draw with replacement: sample(c(0, 1), 100, replace = TRUE) simulates 100 binary draws (an example from the R documentation). The same value can appear repeatedly.
  4. Weight the draw: sample(c("a", "b", "c"), 10, replace = TRUE, prob = c(0.6, 0.3, 0.1)) draws with unequal probabilities.

The single-number trap

If x has length 1, is numeric and is at least 1, sampling takes place from 1:x. So sample(10, 3) draws from 1 to 10, and so does sample(c(10), 3): a subset operation that leaves a single value gives you numbers from 1 to 10, not the value 10 repeated. The R documentation gives a safe wrapper for this: resample <- function(x, ...) x[sample.int(length(x), ...)]. It samples positions, then looks the values up, so a length-one x behaves like any other vector.

How prob works

  • Weights need not sum to one, but must be non-negative and not all zero.
  • With replace = FALSE the weights are applied sequentially, and the number of nonzero weights must be at least size.
  • With replace = TRUE, R uses Walker’s alias method when there are more than 200 reasonably probable values.

Weighted draws change the probability of selection. They do not turn a convenience sample into a representative one, and weights cannot recover population statistics that the sampling frame never contained.

sample.int for large ranges

sample.int(n, size = n) is the bare interface: n and size must be integers, and it samples from 1:n. The documentation example sample.int(1e10, 12, replace = TRUE) draws from a range too large to write out as a vector.

Sample rows from a data frame

There is no special row function in base R. Sample the row numbers and index the data frame with them. Here df stands for any data frame you have loaded:

set.seed(2026)
idx <- sample(nrow(df), 100)   # 100 distinct row numbers
subset_df <- df[idx, ]

Because nrow(df) is a single number of at least 1, this uses the “sample from 1:x” rule deliberately. For a with-replacement draw (bootstrap resample) use df[sample(nrow(df), replace = TRUE), ].

slice_sample() in dplyr

The documented signature is slice_sample(.data, ..., n, prop, by = NULL, weight_by = NULL, replace = FALSE).

  • Supply either n, the number of rows, or prop, the proportion of rows. If neither is given, one row is returned.
  • If n is larger than the group size, it is truncated to the group size. prop is rounded toward zero.
  • weight_by takes a non-negative value per row, standardised to sum to 1 and passed to the prob argument of base::sample.int().
  • On grouped data the sample is drawn within each group; by is a tidy-select alternative to group_by().

Examples from the dplyr reference, using the built-in mtcars data:

library(dplyr)
mtcars |> slice_sample(n = 5)                  # 5 random rows
mtcars |> slice_sample(n = 5, replace = TRUE)  # with replacement
mtcars |> slice_sample(prop = 1)               # shuffles all rows
mtcars |> slice_sample(weight_by = wt, n = 5)  # weighted by wt

A fixed number per group, such as a stratified draw of 5 cars per cylinder count, follows from the grouped behaviour: mtcars |> slice_sample(n = 5, by = cyl). A group with fewer than 5 rows returns all its rows. See grouping in R for related group_by() patterns.

sample_n() and sample_frac() are superseded

The dplyr reference marks sample_n() and sample_frac() as superseded in favour of slice_sample(), and states they will not be deprecated in the near future. Existing code keeps working; new code should use slice_sample().

Older call Current equivalent
sample_n(tbl, size) slice_sample(tbl, n = size)
sample_frac(tbl, size) slice_sample(tbl, prop = size)
sample_n(tbl, size, weight = w) slice_sample(tbl, n = size, weight_by = w)

Output and how to read it

sample() returns a vector of length size containing elements of x (or of 1:x). A row-index draw returns a data frame whose row names keep the original row numbers, so you can see which records were selected. slice_sample() returns the same type of table it was given. Because the result depends on the random number generator, report the seed and the R version with your analysis; the documentation points to RNGkind for the change in sample() results with R 3.6.0. See computational reproducibility.

Troubleshooting

  • Error when size exceeds the number of items. With replace = FALSE you cannot draw more items than exist. Lower size or set replace = TRUE. In dplyr, slice_sample() instead truncates n to the group size.
  • Results differ from a colleague’s. Different seeds, or different R versions around the 3.6.0 change, produce different draws.
  • Unexpected values from a single number. See the single-number trap above; use the resample() wrapper.
  • Weights rejected. Weights must be non-negative and not all zero, and without replacement there must be at least size nonzero weights.
  • Need to drop sampled rows afterwards. See removing rows in R.

Free alternatives

Approach Package Use
sample(), sample.int() base R Sample vectors or row numbers
slice_sample() dplyr Sample rows by count or proportion, grouped or weighted
sample_n(), sample_frac() dplyr (superseded) Older row-sampling calls kept for existing code

FAQ

What does the sample function in R do?

It takes a random selection of size elements from a vector x, without replacement unless replace = TRUE, optionally with probability weights in prob.

How do I randomly sample rows from a data frame in R?

Use df[sample(nrow(df), n), ] in base R or slice_sample(df, n = n) in dplyr.

What replaced sample_n() in R?

dplyr’s slice_sample(). sample_n() and sample_frac() are marked superseded but are not slated for removal soon.

Do the prob weights need to sum to 1?

No. They must be non-negative and not all zero.

Sources

Follow CASRAI

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

Ask CASRAI · free to try

Ask about Sample in R: sample() Function, Syntax and Data Frame Rows

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 →