从R中的data.frame中删除整列


267

有谁知道如何从R中的data.frame中删除整个列?例如,如果我得到此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

我想删除第二列。


Answers:


414

您可以将其设置为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

正如评论中指出的那样,这里还有其他一些可能性:

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

您可以通过以下方式删除多列:

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

不过,请谨慎使用矩阵子集,因为您可能会得到一个向量:

Data <- Data[,-(2:3)]             # vector
Data <- Data[,-(2:3),drop=FALSE]  # still a data.frame

48
或使用以下命令:Data <-Data [,-2]
Ian Fellows

2
使用逗号,您还可以控制“ drop”参数,当结果仅由一列组成时,如果FALSE表示data.frame保留为data.frame,则使用逗号-如果没有逗号,则始终会得到data.frame左或只是一个-降为[-2]萃取忽略
mdsumner

3
@mdsumner Data[-2]不需要drop参数,因为它总是data.frame从返回data.frame。而且我认为这是将列(且仅列)本地化的一种更好的方法data.frame(而且速度更快)。检查:(cars[-1]一个col data.frame)或更好cars[-(1:2)]data frame with 0 columns and 50 rows
Marek

1
您还可以写Data [2] <
-NULL

11
小贴士:Data[c(1,2)]<-list(NULL)需要移除多个列时。
Marek

69

要按名称删除一个或多个列,当知道列名(而不是在运行时确定)时,我喜欢这种subset()语法。例如,数据框

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

删除仅a您可以做的列

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

并删除您可以做的bd

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

您可以删除之间的所有列d,并b用:

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

就像我在上面说的那样,这种语法仅在列名已知时才有效。如果说以编程方式确定列名(即分配给变量),则它将不起作用。我将从?subset文档中重现此警告:

警告:

这是旨在交互使用的便利功能。对于编程,最好使用“ [”之类的标准子集函数,尤其是对参数“子集”的非标准评估会产生意想不到的后果。


26

(出于完整性考虑)如果要按名称删除列,可以执行以下操作:

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]

包括在内drop = F可确保data.frame即使仅保留一列,结果仍将是a 。


22

使用data.frames 时,发布的答案非常好。但是,从内存角度来看,这些任务的效率可能非常低。对于大数据,删除列可能会花费非常长的时间和/或由于out of memory错误而失败。软件包data.table可帮助:=操作员解决此问题:

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

我应该举一个更大的例子来说明差异。我将在某个时候更新此答案。


3
data.table::set可以在上使用该函数,以在data.frame不进行复制的情况下立即删除或修改列。见这里
GSEE

8

有几个选项可用于删除带有dplyr::select()一个辅助功能的一个或多个列。帮助器功能很有用,因为某些功能不需要命名要删除的所有特定列。请注意,要使用删除列,select()您需要使用前导-符来否定列名。

dplyr::starwars样本数据用于某些列名称中:

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 

您还可以按列号删除:

starwars %>% 
  select(-2, -(4:10)) # column 2 and columns 4 through 10

好答案。关于如何删除在任何行中包含某个值的列的想法(不是您上面建议的列名)?
劳拉·K

df [,-which(sapply(df,function(x)any(x == a))))],其中df是您的数据帧,而a是您的特定值,例如:mtcars [,-which(sapply(mtcars, function(x)any(x == 4)))]
Nanami

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.