Удалить весь столбец из data.frame в R


267

Кто-нибудь знает, как удалить весь столбец из data.frame в R? Например, если мне дают эти 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

и я хочу удалить 2-й столбец.


1
Возможный дубликат столбцов Drop в кадре данных R
jangorecki

Ответы:


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
или вы можете использовать: Данные <- Данные [, - 2]
Ян 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](один столбец data.frame) или лучше cars[-(1:2)]: data frame with 0 columns and 50 rows.
Марек

1
Вы также можете написать данные [2] <- NULL
Войцех Собала

11
Незначительный совет: при удалении необходимо несколько столбцов Data[c(1,2)]<-list(NULL).
Марек

69

Чтобы удалить один или несколько столбцов по имени, когда имена столбцов известны (в отличие от определения во время выполнения), мне нравится subset()синтаксис. Например, для фрейма данных

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

удалить только aстолбец, который вы могли бы сделать

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

и удалить bи dстолбцы , которые вы могли бы сделать

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четным, если останется только один столбец.


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

Отличный ответ. Любая идея о том, как удалить столбец, который содержит определенное значение в любой из своих строк (не в имени столбца, как вы предложили выше)?
Лаура К

df [, - which (sapply (df, function (x) any (x == a)))], где df - ваш фрейм данных, а a - ваше конкретное значение, например: mtcars [, - which (sapply (mtcars, function (x) any (x == 4)))]
Нанами

7

При этом вы можете удалить columnи сохранить variableв другом variable.

df = subset(data, select = -c(genome) )
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.