Drop Columns from an R Data Frame

In this tutorial, you will learn how to delete one or more columns from a data frame in R. The examples cover removing columns by index, column name, a vector of names, dplyr::select(), the last column, and matching name patterns.

In R, dropping columns usually means creating a subset that excludes the unwanted variables. The original data frame remains unchanged unless you assign the result back to the same object.

R Syntax to Drop Columns by Index

To remove columns by position, provide their column numbers as negative indices:

</>
Copy
 mydataframe[-c(column_index_1, column_index_2)]

where

  • mydataframe is the data frame.
  • column_index_1, column_index_2, ... are the positions of the columns to exclude.
  • The returned object contains all rows and only the remaining columns.

You can also write the row-and-column form explicitly as mydataframe[, -c(2, 3)]. In that form, the empty position before the comma means all rows are retained.

Example 1: Drop One Column from an R Data Frame

First, create a data frame named DF1.

</>
Copy
> DF1 = data.frame(V1= c(1, 5, 14, 23, 54), V2= c(9, 15, 85, 3, 42), V3= c(9, 7, 42, 87, 16))
> DF1
  V1 V2 V3
1  1  9  9
2  5 15  7
3 14 85 42
4 23  3 87
5 54 42 16
>

Suppose that V2 must be removed. Its column position is 2, so use -2 and assign the resulting data frame to DF2.

</>
Copy
> DF2 = DF1[-2]
> DF2
  V1 V3
1  1  9
2  5  7
3 14 42
4 23 87
5 54 16
>

DF2 contains V1 and V3, while DF1 is unchanged.

Example 2: Delete Multiple Columns from an R Data Frame

Create a data frame with six columns for the multiple-column example.

</>
Copy
> DF1 = data.frame(V1= c(1, 5, 14, 23, 54), V2= c(9, 15, 85, 3, 42), V3= c(9, 7, 42, 87, 16), V4= c(17, 25, 14, 23, 54), V5= c(9, 15, 85, 43, 2), V6= c(9, 75, 4, 7, 6))
> DF1
  V1 V2 V3 V4 V5 V6
1  1  9  9 17  9  9
2  5 15  7 25 15 75
3 14 85 42 14 85  4
4 23  3 87 23 43  7
5 54 42 16 54  2  6
>

To remove V2 and V3, exclude column positions 2 and 3.

</>
Copy
> DF2 = DF1[c(-2,-3)]
> DF2
  V1 V4 V5 V6
1  1 17  9  9
2  5 25 15 75
3 14 14 85  4
4 23 23 43  7
5 54 54  2  6
> 

The result contains every row and all columns except the second and third columns.

Drop an R Data Frame Column by Name

Removing a column by name is usually clearer than relying on its position. One direct base R method is to assign NULL to the column.

</>
Copy
employees <- data.frame(
  name = c("Asha", "Ben", "Chen"),
  department = c("Sales", "Support", "Finance"),
  score = c(84, 76, 91)
)

employees$score <- NULL
  name department
1 Asha      Sales
2  Ben    Support
3 Chen    Finance

This method modifies the object when the assignment is executed. It is convenient for deleting one known column.

Remove Multiple R Columns by Name

To remove several columns by name, use a character vector together with %in% and names():

</>
Copy
employees <- data.frame(
  id = 1:3,
  name = c("Asha", "Ben", "Chen"),
  department = c("Sales", "Support", "Finance"),
  score = c(84, 76, 91)
)

columns_to_remove <- c("department", "score")
result <- employees[, !names(employees) %in% columns_to_remove, drop = FALSE]
  id name
1  1 Asha
2  2  Ben
3  3 Chen

The expression checks each column name against the removal vector and retains the names that are not present.

Remove Columns from an R Data Frame with dplyr select()

The dplyr::select() function removes columns when their names are prefixed with a minus sign.

</>
Copy
library(dplyr)

result <- employees %>%
  select(-department, -score)

You can also pass a character vector safely with all_of():

</>
Copy
columns_to_remove <- c("department", "score")

result <- employees %>%
  select(-all_of(columns_to_remove))

all_of() expects every supplied column name to exist. Use any_of() when the vector may contain names that are not present in the data frame.

</>
Copy
result <- employees %>%
  select(-any_of(c("department", "score", "missing_column")))

Drop R Columns by Name Pattern

Column-selection helpers are useful when several variable names share a prefix, suffix, or text pattern. The following example removes every column whose name starts with temp_:

</>
Copy
measurements <- data.frame(
  id = 1:3,
  temp_morning = c(18, 20, 19),
  temp_evening = c(25, 27, 26),
  humidity = c(62, 58, 65)
)

result <- measurements %>%
  select(-starts_with("temp_"))
  id humidity
1  1       62
2  2       58
3  3       65

Other useful helpers include ends_with(), contains(), and matches().

Remove R Data Frame Columns by Number

When column positions are known, remove them with negative numeric indices. The following statement deletes columns 2 through 4:

</>
Copy
result <- DF1[, -(2:4), drop = FALSE]

Using drop = FALSE keeps the result as a data frame even when only one column remains.

Remove the Last Column from an R Data Frame

Use ncol() to obtain the current position of the last column:

</>
Copy
result <- DF1[, -ncol(DF1), drop = FALSE]

This approach continues to work when the number of columns changes.

With dplyr, the last column can be removed by selecting all columns except the final position:

</>
Copy
result <- DF1 %>%
  select(-last_col())

Keep Selected Columns Instead of Dropping Others

When only a small number of columns are needed, it can be clearer to specify the columns to retain rather than list every column to remove.

</>
Copy
result <- employees[c("id", "name")]

The equivalent dplyr operation is:

</>
Copy
result <- employees %>%
  select(id, name)

Drop Columns Based on R Data Types

You can remove columns according to their data type. This example keeps only columns that are not numeric:

</>
Copy
result <- employees[, !vapply(employees, is.numeric, logical(1)), drop = FALSE]

With dplyr, use where() to select or exclude columns based on a predicate:

</>
Copy
result <- employees %>%
  select(-where(is.numeric))

Avoid Invalid Column Names and Indices in R

When column names or positions come from user input, validate them before subsetting. The following base R example removes only names that actually exist:

</>
Copy
requested_columns <- c("department", "score", "unknown")
existing_columns <- intersect(requested_columns, names(employees))

result <- employees[, !names(employees) %in% existing_columns, drop = FALSE]

For numeric positions, retain only values between 1 and ncol():

</>
Copy
columns_to_remove <- c(2, 4, 20)
valid_columns <- columns_to_remove[
  columns_to_remove >= 1 & columns_to_remove <= ncol(DF1)
]

result <- DF1[, -valid_columns, drop = FALSE]

Common Mistakes When Dropping R Data Frame Columns

  • Using row syntax by mistake: df[-2, ] removes the second row, while df[-2] or df[, -2] removes the second column.
  • Forgetting assignment: df[, -2] returns a subset but does not replace df unless the result is assigned.
  • Mixing positive and negative indices: R does not allow positive and negative subscript values in the same index vector, except for zeros.
  • Dropping to a vector: Selecting one column with matrix-style indexing may simplify the result. Use drop = FALSE when a data frame must be preserved.
  • Using missing names with all_of(): Use any_of() when some requested column names may not exist.

Frequently Asked Questions About Dropping Columns in R

How do I drop a column by name in R?

Assign NULL to the column, as in df$column_name <- NULL, or subset with df[, names(df) != "column_name", drop = FALSE].

How do I remove multiple columns in R?

Use negative positions such as df[, -c(2, 4)], or remove names with df[, !names(df) %in% c("a", "b"), drop = FALSE].

How do I remove columns with dplyr?

Use select() with negative column names, for example df %>% select(-status, -score). For a character vector, use select(-all_of(column_names)).

How do I remove the last column in an R data frame?

Use df[, -ncol(df), drop = FALSE] in base R or df %>% select(-last_col()) with dplyr.

Does dropping a column change the original data frame?

Subsetting returns another object. The original changes only when you assign the result back, such as df <- df[, -2], or directly assign NULL to a column.

Editorial QA Checklist for R Column-Removal Examples

  • Confirm that numeric examples distinguish column indexing from row indexing.
  • Verify that examples using one remaining column include drop = FALSE when a data frame result is expected.
  • Check that character-vector examples use all_of() or any_of() correctly with dplyr::select().
  • Ensure that examples state whether the original data frame is modified or a new object is created.
  • Test that every named column in an output block matches the columns retained by the code.

R Data Frame Column Removal Summary

Use negative numeric indices when column positions are known, character-name matching when names are more reliable, and dplyr::select() for tidyverse workflows. Assign NULL to remove one named column directly, and use drop = FALSE when the result must remain a data frame.

In this R Tutorial, we have learned how to delete or drop one or multiple columns from an R DataFrame by position, name, pattern, and data type.