Remove an entire column from a data.frame in R
Asked Answered
D

9

320

Does anyone know how to remove an entire column from a data.frame in R? For example if I am given this data.frame:

> head(data)
   chr       genome region
1 chr1 hg19_refGene    CDS
2 chr1 hg19_refGene   exon
3 chr1 hg19_refGene    CDS
4 chr1 hg19_refGene   exon
5 chr1 hg19_refGene    CDS
6 chr1 hg19_refGene   exon

and I want to remove the 2nd column.

Djebel answered 8/6, 2011 at 23:2 Comment(1)
Possible duplicate of Drop columns in R data frameSudduth
K
492

You can set it to NULL.

> Data$genome <- NULL
> head(Data)
   chr region
1 chr1    CDS
2 chr1   exon
3 chr1    CDS
4 chr1   exon
5 chr1    CDS
6 chr1   exon

As pointed out in the comments, here are some other possibilities:

Data[2] <- NULL    # Wojciech Sobala
Data[[2]] <- NULL  # same as above
Data <- Data[,-2]  # Ian Fellows
Data <- Data[-2]   # same as above

You can remove multiple columns via:

Data[1:2] <- list(NULL)  # Marek
Data[1:2] <- NULL        # does not work!

Be careful with matrix-subsetting though, as you can end up with a vector:

Data <- Data[,-(2:3)]             # vector
Data <- Data[,-(2:3),drop=FALSE]  # still a data.frame
Kirbee answered 8/6, 2011 at 23:6 Comment(9)
or you can use: Data <- Data[,-2]Cheatham
@Ian do you even need the ","?Foolproof
with the comma you can also control the "drop" argument, which when FALSE means the data.frame stays a data.frame when the result consists of only one column - without the comma you will always get a data.frame whether multiple columns are left or just one - drop is ignored for the [-2] extractionTransudation
@Transudation Data[-2] don't need drop argument cause it always return data.frame from data.frame. And I think this is much better way to localized columns (and only columns) in data.frame (and it's faster). Check: cars[-1] (one col data.frame) or better cars[-(1:2)]: data frame with 0 columns and 50 rows.Cf
You can also write Data[2] <- NULLPrank
Minor tip: When removing multiple columns Data[c(1,2)]<-list(NULL) is needed.Cf
how to remove them by calling names of columns?Chrisom
does anyone know when this would fail? Calling it twice in a row works. But, calling names(x), x$y<-null, names(x) shows y during the second call to names(). Specifically, I have four DFs with one common column. It works on only three of the fourObvolute
@MikePalmice: You should ask a new question.Kirbee
P
86

To remove one or more columns by name, when the column names are known (as opposed to being determined at run-time), I like the subset() syntax. E.g. for the data-frame

df <- data.frame(a=1:3, d=2:4, c=3:5, b=4:6)

to remove just the a column you could do

Data <- subset( Data, select = -a )

and to remove the b and d columns you could do

Data <- subset( Data, select = -c(d, b ) )

You can remove all columns between d and b with:

Data <- subset( Data, select = -c( d : b )

As I said above, this syntax works only when the column names are known. It won't work when say the column names are determined programmatically (i.e. assigned to a variable). I'll reproduce this Warning from the ?subset documentation:

Warning:

This is a convenience function intended for use interactively. For programming it is better to use the standard subsetting functions like '[', and in particular the non-standard evaluation of argument 'subset' can have unanticipated consequences.

Peggiepeggir answered 9/6, 2011 at 2:31 Comment(0)
E
38

(For completeness) If you want to remove columns by name, you can do this:

cols.dont.want <- "genome"
cols.dont.want <- c("genome", "region") # if you want to remove multiple columns

data <- data[, ! names(data) %in% cols.dont.want, drop = F]

Including drop = F ensures that the result will still be a data.frame even if only one column remains.

Eachern answered 3/6, 2015 at 13:4 Comment(0)
C
24

The posted answers are very good when working with data.frames. However, these tasks can be pretty inefficient from a memory perspective. With large data, removing a column can take an unusually long amount of time and/or fail due to out of memory errors. Package data.table helps address this problem with the := operator:

library(data.table)
> dt <- data.table(a = 1, b = 1, c = 1)
> dt[,a:=NULL]
     b c
[1,] 1 1

I should put together a bigger example to show the differences. I'll update this answer at some point with that.

Citation answered 19/7, 2012 at 16:40 Comment(1)
The data.table::set function can be used on data.frames to remove or modify a column instantly, without making copies. See hereReiche
Z
12

With this you can remove the column and store variable into another variable.

df = subset(data, select = -c(genome) )
Zambrano answered 4/8, 2017 at 4:53 Comment(0)
B
12

There are several options for removing one or more columns with dplyr::select() and some helper functions. The helper functions can be useful because some do not require naming all the specific columns to be dropped. Note that to drop columns using select() you need to use a leading - to negate the column names.

Using the dplyr::starwars sample data for some variety in column names:

library(dplyr)

starwars %>% 
  select(-height) %>%                  # a specific column name
  select(-one_of('mass', 'films')) %>% # any columns named in one_of()
  select(-(name:hair_color)) %>%       # the range of columns from 'name' to 'hair_color'
  select(-contains('color')) %>%       # any column name that contains 'color'
  select(-starts_with('bi')) %>%       # any column name that starts with 'bi'
  select(-ends_with('er')) %>%         # any column name that ends with 'er'
  select(-matches('^v.+s$')) %>%       # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%          # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

You can also drop by column number:

starwars %>% 
  select(-2, -(4:10)) # column 2 and columns 4 through 10
Barncard answered 20/3, 2019 at 2:19 Comment(2)
Great answer. Any idea on how to drop a column that contains a certain value in any of its rows (not in its column name as you proposed above)?Konrad
df[,-which(sapply(df, function(x) any(x == a)))], where df is your data frame and a is your specific value, e.g.: mtcars[,-which(sapply(mtcars, function(x) any(x==4)))]Djebel
P
2

Using dplyR, the following works:

data <- select(data, -genome)

as per documentation found here https://www.marsja.se/how-to-remove-a-column-in-r-using-dplyr-by-name-and-index/#:~:text=select(starwars%2C%20%2Dheight)

Prelature answered 31/8, 2022 at 3:0 Comment(0)
W
1

I just thought I'd add one in that wasn't mentioned yet. It's simple but also interesting because in all my perusing of the internet I did not see it, even though the highly related %in% appears in many places.

df <- df[ , -which(names(df) == 'removeCol')]

Also, I didn't see anyone post grep alternatives. These can be very handy for removing multiple columns that match a pattern.

Whinny answered 11/11, 2022 at 2:19 Comment(1)
With logical, one can also go with df <- df[ , !names(df) == 'removeCol']Duumvir
G
0

chr = chr[,-2] It's easier if you do this way, just remove the second column from the df and store it in the df again.

Glycoprotein answered 3/10, 2023 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.