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

Posted

技术标签:

【中文标题】从 R 中的 data.frame 中删除一整列【英文标题】:Remove an entire column from a data.frame in R 【发布时间】:2011-09-11 07:03:24 【问题描述】:

有谁知道如何从 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

我想删除第二列。

【问题讨论】:

Drop columns in R data frame的可能重复 【参考方案1】:

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

正如 cmets 中所指出的,还有其他一些可能性:

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

【讨论】:

或者你可以使用:Data 使用逗号,您还可以控制“drop”参数,当 FALSE 表示当结果仅包含一列时 data.frame 保持为 data.frame - 没有逗号,您将始终得到一个data.frame,无论是多列还是只剩下一列- [-2] 提取将忽略丢弃 @mdsumner Data[-2] 不需要drop 参数,因为它总是从data.frame 返回data.frame。而且我认为这是在data.frame 中本地化列(并且仅列)的更好方法(而且速度更快)。检查:cars[-1](一列data.frame)或更好cars[-(1:2)]data frame with 0 columns and 50 rows 也可以写Data[2] 小提示:删除多列时需要Data[c(1,2)]&lt;-list(NULL)【参考方案2】:

要按名称删除一个或多个列,当列名已知时(而不是在运行时确定),我喜欢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 ) )

您可以删除db 之间的所有列:

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

正如我上面所说,这种语法只有在列名已知时才有效。当说以编程方式确定列名(即分配给变量)时,它将不起作用。我将从?subset 文档中复制此警告:

警告:

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

【讨论】:

【参考方案3】:

使用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

我应该整理一个更大的例子来展示差异。我会在某个时候更新这个答案。

【讨论】:

data.table::set 函数可用于data.frames 以立即删除或修改列,而无需复制。见here【参考方案4】:

(为了完整性)如果要按名称删除列,可以这样做:

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

【讨论】:

【参考方案5】:

有了这个你可以删除column并将variable存储到另一个variable中。

df = subset(data, select = -c(genome) )

【讨论】:

【参考方案6】:

有几个选项可以使用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

【讨论】:

很好的答案。关于如何删除在其任何行中包含特定值的列(而不是您上面建议的列名)的任何想法? df[,-which(sapply(df, function(x) any(x == a)))],其中 df 是您的数据框,a 是您的特定值,例如:mtcars[ ,-which(sapply(mtcars, function(x) any(x==4)))]

以上是关于从 R 中的 data.frame 中删除一整列的主要内容,如果未能解决你的问题,请参考以下文章

什么函数允许我根据R中列中的值从数据框中的列中提取数据?

根据条件从 r 中的多列中删除重复的行

在 R 中获取 data.frame 中元素差异的最快方法

如何从包含在单个列中的文本构建 data.frame?

如何检查和删除一列中的字符串是否与R中另一列中的字符串匹配

从R中的多个数据框中删除同一列