Удалить столбцы фрейма данных по имени - PullRequest
773 голосов
/ 05 января 2011

У меня есть несколько столбцов, которые я хотел бы удалить из фрейма данных. Я знаю, что мы можем удалить их по отдельности, используя что-то вроде:

df$x <- NULL

Но я надеялся сделать это с меньшим количеством команд.

Кроме того, я знаю, что я мог бы отбрасывать столбцы, используя целочисленную индексацию, например:

df <- df[ -c(1, 3:6, 12) ]

Но я обеспокоен тем, что относительное положение моих переменных может измениться.

Учитывая, насколько мощный R, я подумал, что может быть лучший способ, чем отбрасывать каждый столбец один за другим.

Ответы [ 20 ]

19 голосов
/ 11 января 2012

Другая возможность:

df <- df[, setdiff(names(df), c("a", "c"))]

или

df <- df[, grep('^(a|c)$', names(df), invert=TRUE)]
18 голосов
/ 27 августа 2014

Вот способ dplyr:

#df[ -c(1,3:6, 12) ]  # original
df.cut <- df %>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)  # with dplyr::select()

Мне нравится это, потому что это интуитивно понятно и понятно без аннотации и устойчиво к изменению положения столбцов в кадре данных.Он также следует векторизованной фразеологии, используя - для удаления элементов.

16 голосов
/ 31 января 2018

Dplyr Solution

Я сомневаюсь, что здесь будет много внимания, но если у вас есть список столбцов, которые вы хотите удалить, и вы хотите сделать это в цепочке dplyr, я использую one_of() в предложении select :

Вот простой, воспроизводимый пример:

undesired <- c('mpg', 'cyl', 'hp')

mtcars <- mtcars %>%
  select(-one_of(undesired))

Документацию можно найти, запустив ?one_of или здесь:

http://genomicsclass.github.io/book/pages/dplyr_tutorial.html

13 голосов
/ 05 января 2011

Я продолжаю думать, что должна быть лучшая идиома, но для вычитания столбцов по имени я склонен делать следующее:

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)

# return everything except a and c
df <- df[,-match(c("a","c"),names(df))]
df
11 голосов
/ 04 декабря 2014

В пакете BBmisc Бернда Бишла есть функция с именем dropNamed(), которая делает именно это.

BBmisc::dropNamed(df, "x")

Преимущество состоит в том, что она избегает повторения аргумента фрейма данных и, таким образом, подходит для передачи по трубам magrittr (точно так же как dplyr подходы):

df %>% BBmisc::dropNamed("x")
7 голосов
/ 26 октября 2016

Другое решение, если вы не хотите использовать @ hadley выше: если "COLUMN_NAME" - это имя столбца, который вы хотите удалить:

df[,-which(names(df) == "COLUMN_NAME")]
5 голосов
/ 03 июля 2018

За пределами select(-one_of(drop_col_names)), продемонстрированное в предыдущих ответах, есть пара других dplyr опций для удаления столбцов с использованием select(), которые не включают в себя определение всех конкретных имен столбцов (с использованием образца данных dplyr starwars для некоторого разнообразия в столбцеимена):

library(dplyr)
starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  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('^f.+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 
3 голосов
/ 15 июня 2018

Укажите фрейм данных и строку имен, разделенных запятыми для удаления:

remove_features <- function(df, features) {
  rem_vec <- unlist(strsplit(features, ', '))
  res <- df[,!(names(df) %in% rem_vec)]
  return(res)
}

Использование :

remove_features(iris, "Sepal.Length, Petal.Width")

enter image description here

1 голос
/ 03 августа 2018

Найдите индекс столбцов, которые вы хотите удалить, используя which. Дайте этим индексам отрицательный знак (*-1). Затем подмножество тех значений, которые будут удалять их из кадра данных. Это пример.

DF <- data.frame(one=c('a','b'), two=c('c', 'd'), three=c('e', 'f'), four=c('g', 'h'))
DF
#  one two three four
#1   a   d     f    i
#2   b   e     g    j

DF[which(names(DF) %in% c('two','three')) *-1]
#  one four
#1   a    g
#2   b    h
0 голосов
/ 06 июля 2019

Вы также можете сделать это:

 i<-which( colnames(df)=="COLumn")
 df<-df[,-i]
...