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

Subset in R: subset(), [ ] and slice() with Examples

How to subset in R: subset(), [ ], [[ ]] and dplyr slice(), with documented examples, NA handling and when to avoid subset() in scripts.

Written and maintained by CASRAI Editorial Board

Last updated

Subset in R means keeping only the rows, columns or elements of a vector, matrix, list or data frame that meet a condition or position. The base function subset() does this for a condition, [ ] and [[ ]] do it by index, and dplyr’s slice() does it by row position. This guide shows which one to use, with the examples from R’s own documentation, and the rule that trips people up: subset() treats NA as false and is documented as an interactive convenience, not a scripting tool.

What subsetting is used for in research

Research analysis rarely runs on a whole dataset. You restrict to a cohort, a time window, a treatment arm or a set of variables, then analyse that part. In R this is the step between loading data (see data frames in R) and modelling. Choosing the right tool matters because the tools differ on missing values, on what they return and on whether they are safe inside a function or script.

Install or access

subset(), [ ] and [[ ]] are part of base R, so there is nothing to install beyond R itself, which is distributed by CRAN (cran.r-project.org). slice() belongs to the dplyr package, installed once from CRAN and loaded in each session:

install.packages("dplyr")
library(dplyr)

Step-by-step: subset a data frame with subset()

The documented usage for data frames and matrices is subset(x, subset, select, drop = FALSE, ...). The examples below use airquality, a data frame that ships with R and is used in the R manual’s own examples.

  1. Keep rows by a condition. The subset argument is a logical expression, evaluated inside the data frame, so you name columns directly: subset(airquality, Temp > 80).
  2. Keep rows and chosen columns. Add select: subset(airquality, Temp > 80, select = c(Ozone, Temp)).
  3. Drop a column. Use a negative: subset(airquality, Day == 1, select = -Temp).
  4. Keep a range of columns. Column names are converted to positions, so a range works: subset(airquality, select = Ozone:Wind).
  5. Combine conditions. Join logical tests with & (and) or | (or), for example subset(airquality, Temp > 80 & Month == 7). See the OR operator in R for how | differs from ||.
  6. Subset a vector. Use with(airquality, subset(Ozone, Temp > 80)), which returns the Ozone values where the condition holds.

Output and how to read it

For a data frame, subset() returns a data frame with the same columns (or the ones you selected) and only the matching rows; row names keep their original numbers, so gaps in the row labels are expected. For a vector it returns a vector. Two behaviours in the R documentation affect how you read the result:

  • Missing values count as false. Rows where the condition evaluates to NA are dropped, not kept. For vectors, subset() is essentially x[subset & !is.na(subset)]. In airquality, where Ozone has missing values, a filter on Ozone silently removes the NA rows. Check how many rows you lost with nrow() before and after.
  • Factors keep unused levels. After subsetting, a factor column still lists levels that no longer occur. Apply droplevels() to remove them before tabulating or plotting.

Subset with [ ] and [[ ]]

An Introduction to R describes four kinds of index vector for [ ]: a logical vector, positive integers (select), negative integers (exclude) and character strings (match names). For example, y <- x[!is.na(x)] keeps the non-missing values. Data frames follow matrix conventions, df[rows, columns].

Unlike subset(), an NA in a logical index passed to [ ] yields an NA element or row rather than silently dropping it, which makes the problem visible. This is one reason the documentation points scripts and functions towards [ ] and [[ ]].

What does [[ 1 ]] do in R?

[[ 1 ]] extracts the single first element of a list, as the element itself. [ 1 ] returns a sub-list of length one that still has its name. An Introduction to R puts it this way: “It is very important to distinguish Lst[[1]] from Lst[1].” Also, Lst$name is equivalent to Lst[["name"]], but $ allows a unique abbreviation and [[ ]] accepts a variable holding the name, which $ does not.

What does slice() do in R?

dplyr’s slice() indexes rows by their integer positions. Negative positions drop rows, and positions can repeat, which duplicates rows. Its helpers cover common cases: slice_head() and slice_tail() take the first or last rows (by n or prop), slice_sample() takes a random set (see sample in R), and slice_min() and slice_max() take rows by the smallest or largest values of a column. On grouped data the helpers run per group. Because slice() depends on row order, it does not work with relational databases; dplyr’s documentation suggests filter() with row_number() there.

Which tool to use

Tool Selects by Missing values in the condition Best for
subset() Logical condition (rows) and column names (select) Treated as false, row dropped Interactive exploration; documented as “a convenience function intended for use interactively”
[ ] Logical, positive, negative or character index Produces NA entries Scripts and functions
[[ ]] One position or name Not applicable (single element) Extracting one list element or column
slice() (dplyr) Integer row position Not applicable (position based) First, last, random or extreme rows

The R manual states that for programming use, [ or [[ are preferred, because the non-standard evaluation in subset() can behave unexpectedly, for instance when a column name clashes with a variable of the same name in your function. Related tasks: selecting columns in R, removing rows in R and ordering data in R.

Troubleshooting

  • Fewer rows than expected. Missing values in the tested column are dropped by subset(). Add is.na() logic explicitly if you want to keep or inspect them.
  • Odd results inside a function. The condition is evaluated within the data frame, so a column can shadow your variable. Use [ ] in functions and scripts.
  • A factor still shows empty categories. Wrap the result in droplevels().
  • A one-column result becomes a vector. The drop argument is passed to [; the documented default for subset() is drop = FALSE, whereas plain df[, "col"] drops to a vector by default.
  • “Object not found” for a column name. Outside subset() columns are not in scope; write df$col or use with().

Free alternatives

Option Where it comes from Use it for
Base R: [ ], [[ ]], $ Included in R (CRAN) Everything in this guide, without extra packages
dplyr slice() family dplyr package (CRAN, tidyverse project) Row selection by position, with grouping support

Questions about the same operation in Python or C++ are different tools with different syntax; for pandas, see the CASRAI guide on pandas drop_duplicates(), whose subset argument is a separate concept.

FAQ

How to subset your data in R?

Use subset(df, condition, select = columns) for quick interactive work, or df[rows, columns] with a logical, positive, negative or named index for scripts. Use slice() from dplyr to select rows by position.

What is a subset in simple terms?

A subset is a smaller part of a larger collection that satisfies a condition or is chosen by position: for example, the rows of a dataset where the temperature is above 80, or only the first column.

What does [[ 1 ]] do in R?

It returns the first element of a list as the element itself, whereas [ 1 ] returns a list of length one containing that element.

What does slice() do in R?

It selects rows of a data frame by integer position, including negative positions to drop rows, with helpers such as slice_head(), slice_sample() and slice_max().

Sources

Follow CASRAI

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

Ask CASRAI · free to try

Ask about Subset in R: subset(), [ ] and slice() with 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 →